假设我试图在Windows上自动安装某些东西,我想在尝试安装之前尝试testing是否有其他安装正在进行。 我无法控制安装程序,必须在自动化框架中执行此操作。 有没有更好的方法来做到这一点,一些win32 API?,而不是只是testing,如果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; }
请参阅MSDN上_MSIExecute Mutex的说明。
我正在使用上面的代码得到一个未处理的异常。 我交叉引用这篇文章这一个
这是我更新的代码:
/// <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