代码之家  ›  专栏  ›  技术社区  ›  Wedge

如何测试另一个安装是否已在进行中?

  •  7
  • Wedge  · 技术社区  · 17 年前

    假设我正在尝试在windows上自动安装某些东西,并且在尝试安装之前,我想尝试测试另一个安装是否正在进行中。我无法控制安装程序,只能在自动化框架中进行。有没有比测试msiexec是否正在运行更好的方法,一些win32 api?

    改进了我以前直接访问互斥锁的代码,这更加可靠:

    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;
    }
    
    3 回复  |  直到 6 年前
        1
  •  6
  •   Mike Dimmick    17 年前

    请参见对的描述 _MSIExecute Mutex 在MSDN上。

        2
  •  3
  •   Community Mohan Dere    9 年前

    one

    以下是我的更新代码:

      /// <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;
    
    }
    
        3
  •  2
  •   StayOnTarget Charlie Flowers    5 年前

    我已经用你的笔记(谢谢)和其他网站上的笔记写了一个星期了——太多了,无法命名(谢谢大家)。

    我偶然发现了一些信息,这些信息表明该服务可以产生足够的信息来确定MSIEXEC服务是否已经在使用中。服务是“msiserver”-Windows Installer-并且它的信息是state和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