如何测试,如果另一个安装正在进行中?(How do I test if another instal

2019-07-17 16:29发布

假设我想自动在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;
}

Answer 1:

见的描述_MSIExecute互斥 MSDN上。



Answer 2:

使用上面的代码我得到一个未处理的异常。 我相互参照这篇文章威特这一个

这里是我更新的代码:

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

}


Answer 3:

对不起,劫持您发布!

我一直在这一点 - 大约一个星期 - 使用从其他网站笔记(谢谢),并且 - 太多的域名(谢谢大家)。

我碰到的信息透露,该服务可能会产生足够的信息,以确定是否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


文章来源: How do I test if another installation is already in progress?