Как проверить, выполняется ли уже другая установка?

StackOverflow https://stackoverflow.com/questions/140820

  •  02-07-2019
  •  | 
  •  

Вопрос

Предположим, я пытаюсь автоматизировать установку чего-либо в Windows и хочу попробовать проверить, выполняется ли еще одна установка, прежде чем пытаться установить.У меня нет контроля над установщиком, и мне приходится делать это в рамках автоматизации.Есть ли лучший способ сделать это, какой-нибудь Win32 API?, чем просто проверить, работает ли msiexec?

[Обновление 2]

Улучшен предыдущий код, который я использовал для прямого доступа к мьютексу, он намного надежнее:

using System.Threading;

[...]

/// <summary>
/// Wait (up to a timeout) for the MSI installer service to become free.
/// </summary>
/// <returns>
/// Returns true for a successful wait, when the installer service has become free.
/// Returns false when waiting for the installer service has exceeded the timeout.
/// </returns>
public static bool WaitForInstallerServiceToBeFree(TimeSpan maxWaitTime)
{
    // The _MSIExecute mutex is used by the MSI installer service to serialize installations
    // and prevent multiple MSI based installations happening at the same time.
    // For more info: http://msdn.microsoft.com/en-us/library/aa372909(VS.85).aspx
    const string installerServiceMutexName = "Global\\_MSIExecute";

    try
    {
        Mutex MSIExecuteMutex = Mutex.OpenExisting(installerServiceMutexName, 
            System.Security.AccessControl.MutexRights.Synchronize | System.Security.AccessControl.MutexRights.Modify);
        bool waitSuccess = MSIExecuteMutex.WaitOne(maxWaitTime, false);
        MSIExecuteMutex.ReleaseMutex();
        return waitSuccess;
    }
    catch (WaitHandleCannotBeOpenedException)
    {
        // Mutex doesn't exist, do nothing
    }
    catch (ObjectDisposedException)
    {
        // Mutex was disposed between opening it and attempting to wait on it, do nothing
    }
    return true;
}
Это было полезно?

Решение

Смотрите описание _MSIExecute Мьютекс на MSDN.

Другие советы

Я получал необработанное исключение, используя приведенный выше код.Я сделал перекрестную ссылку на эту статью с этим один

Вот мой обновленный код:

  /// <summary>
/// Wait (up to a timeout) for the MSI installer service to become free.
/// </summary>
/// <returns>
/// Returns true for a successful wait, when the installer service has become free.
/// Returns false when waiting for the installer service has exceeded the timeout.
/// </returns>
public static bool IsMsiExecFree(TimeSpan maxWaitTime)
{
    // The _MSIExecute mutex is used by the MSI installer service to serialize installations
    // and prevent multiple MSI based installations happening at the same time.
    // For more info: http://msdn.microsoft.com/en-us/library/aa372909(VS.85).aspx
    const string installerServiceMutexName = "Global\\_MSIExecute";
    Mutex MSIExecuteMutex = null;
    var isMsiExecFree = false;
    try
    {
            MSIExecuteMutex = Mutex.OpenExisting(installerServiceMutexName,
                            System.Security.AccessControl.MutexRights.Synchronize);
            isMsiExecFree = MSIExecuteMutex.WaitOne(maxWaitTime, false);
    }
        catch (WaitHandleCannotBeOpenedException)
        {
            // Mutex doesn't exist, do nothing
            isMsiExecFree = true;
        }
        catch (ObjectDisposedException)
        {
            // Mutex was disposed between opening it and attempting to wait on it, do nothing
            isMsiExecFree = true;
        }
        finally
        {
            if(MSIExecuteMutex != null && isMsiExecFree)
            MSIExecuteMutex.ReleaseMutex();
        }
    return isMsiExecFree;

}

Извините, что украл ваш пост!

Я работал над этим около недели, используя ваши заметки (спасибо) и заметки с других сайтов — их слишком много, чтобы перечислить (спасибо всем).

Я наткнулся на информацию, показывающую, что служба может предоставить достаточно информации, чтобы определить, используется ли уже служба MSIEXEC.Служба называется «msiserver» — установщик Windows — и ее информация является как состоянием, так и информацией AcceptStop.

Следующий код VBScript проверяет это.

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Check = False
Do While Not Check
   WScript.Sleep 3000
   Set colServices = objWMIService.ExecQuery("Select * From Win32_Service Where Name="'msiserver'")
   For Each objService In colServices
      If (objService.Started And Not objService.AcceptStop)  
         WScript.Echo "Another .MSI is running."
      ElseIf ((objService.Started And objService.AcceptStop) Or Not objService.Started) Then
         WScript.Echo "Ready to install an .MSI application."
         Check = True
      End If
   Next
Loop
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top