Как проверить, выполняется ли другая установка? - PullRequest
8 голосов
/ 26 сентября 2008

Предполагается, что я пытаюсь автоматизировать установку чего-либо в 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);
        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;
}

Ответы [ 3 ]

6 голосов
/ 26 сентября 2008

См. Описание _MSIExecute Mutex в MSDN.

3 голосов
/ 26 февраля 2014

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

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

  /// <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;

}
2 голосов
/ 11 ноября 2015

Извините за угон поста!

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

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

Следующий код 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...