Assuming I'm trying to automate the installation of something on windows and I want to try to test whether another installation is in progress before attempting install. I don't have control over the installer and have to do this in the automation framework. Is there a better way to do this, some win32 api?, than just testing if msiexec is running?
[Update 2]
Improved the previous code I had been using to just access the mutex directly, this is a lot more reliable:
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;
}
See the description of the _MSIExecute Mutex on MSDN.
I was getting an unhandled exception using the code above. I cross referenced this article witt this one
Here's my updated code:
/// <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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With