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

问题描述:

假设我试图在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; 
} 
+2

当您在没有MutexRights.Modify标志的情况下打开现有的互斥锁时,您无法释放该互斥体,因为您无法拥有它。从msdn:MutexRights.Synchronize允许线程等待互斥体,并且MutexRights.Modify允许线程调用ReleaseMutex方法。 http://msdn.microsoft.com/en-us/library/c41ybyt3.aspx – 2011-08-11 17:53:16

_MSIExecute Mutex MSDN上的描述。

我正在使用上面的代码得到未处理的异常。我相互参照这篇文章威特此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; 

} 

对不起劫持您发布!

我一直在为此工作 - 约一个星期 - 使用您的笔记(谢谢)和其他网站 - 太多名称(谢谢大家)。

我偶然发现信息显示服务可能会产生足够的信息来确定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