c# - saber - no se puede ejecutar si la instalacion esta en curso visual studio
¿Cómo pruebo si ya hay otra instalación en progreso? (3)
Suponiendo que estoy tratando de automatizar la instalación de algo en Windows y quiero intentar probar si hay otra instalación en progreso antes de intentar la instalación. No tengo control sobre el instalador y tengo que hacer esto en el marco de automatización. ¿Hay una mejor manera de hacer esto, alguna API de win32 ?, que simplemente probar si se está ejecutando msiexec?
[Actualización 2]
Mejorado el código anterior que había estado usando para acceder al mutex directamente, esto es mucho más confiable:
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;
}
Consulte la descripción de _MSIExecute Mutex en MSDN.
Perdón por secuestrar tu publicación!
He estado trabajando en esto, durante aproximadamente una semana, usando sus notas (gracias) y las de otros sitios; demasiadas para nombrar (gracias a todos).
Me encontré con información que revela que el Servicio podría proporcionar suficiente información para determinar si el servicio MSIEXEC ya está en uso. El servicio es ''msiserver'' - Windows Installer - y su información es tanto state como accepttop.
El siguiente código de VBScript verifica esto.
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
Obtenía una excepción no controlada usando el código anterior. Hice una referencia cruzada de este artículo con este
Aquí está mi código actualizado:
/// <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;
}