2008-09-26 57 views
7

假設我試圖在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

回答

2

我正在使用上面的代碼得到未處理的異常。我相互參照這篇文章威特此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; 

} 
2

對不起劫持您發佈!

我一直在爲此工作 - 約一個星期 - 使用您的筆記(謝謝)和其他網站 - 太多名稱(謝謝大家)。

我偶然發現信息顯示服務可能會產生足夠的信息來確定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 
相關問題