假设我想自动在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;
}
使用上面的代码我得到一个未处理的异常。 我相互参照这篇文章威特这一个
这里是我更新的代码:
/// <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