2010-03-02 22 views
5

Tengo un proyecto Inno Setup que quiero verificar si la aplicación se está ejecutando realmente antes de desinstalarla. Intenté de muchas maneras pero todo falla silenciosamente, cuando se ejecuta en Windows 7. Por ejemplo, el siguiente script que comprueba el proceso notepad.exe usando psvince.dll siempre devuelve false independientemente de si el Bloc de notas se está ejecutando o no.Inno Setup Comprobación del proceso en ejecución

Usé psvince.dll en una aplicación C# para comprobar, si funciona en Windows 7 y funciona sin ningún problema. Así que mi mejor suposición es que el instalador no se puede ejecutar correctamente con UAC habilitado.

[Code] 
function IsModuleLoaded(modulename: String): Boolean; 
external '[email protected]:psvince.dll stdcall'; 

function InitializeSetup(): Boolean; 
begin 
    if(Not IsModuleLoaded('ePub.exe')) then 
    begin 
     MsgBox('Application is not running.', mbInformation, MB_OK); 
     Result := true; 
    end 
    else 
    begin 
     MsgBox('Application is already running. Close it before uninstalling.', mbInformation, MB_OK); 
     Result := false; 
    end 
end; 
+0

Tengo el mismo problema, pero el AnsiString no me ayudó. –

Respuesta

7

¿Estás utilizando Unicode Inno Setup? Si es así, debería decir

function IsModuleLoaded(modulename: AnsiString): Boolean;

ya que psvince.dll no es un dll Unicode.

También el ejemplo busca epub.exe, no notepad.exe.

+0

Tengo el mismo problema, pero el AnsiString no me ayudó. –

+0

http://www.lextm.com/2012/03/new-inno-setup-installer-script-samples.html –

4

Inno Setup en realidad tiene una directiva AppMutex, que está documentada en la ayuda. Implementarlo requiere 2 líneas de código.

En la sección [Configuración] del archivo ISS agrega:

AppMutex=MyProgramsMutexName 

Y luego durante su inicio de la aplicación agregar esta línea de código:

CreateMutex(NULL, FALSE, "MyProgramsMutexName"); 
+1

[Official doc] (http://www.jrsoftware.org/iskb.php?mutexsessions) dice que necesita dos mutexes para detectar instancias iniciadas por otros usuarios. – Igor

5

También puede tratar de utilizar WMIService :

procedure FindApp(const AppName: String); 
var 
    WMIService: Variant; 
    WbemLocator: Variant; 
    WbemObjectSet: Variant; 
begin 
    WbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 
    WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2'); 
    WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"'); 
    if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then 
    begin 
    Log(AppName + ' is up and running'); 
    end; 
end; 
1

Puede usar este código para comprobar si notepad.exe se está ejecutando.

[Code] 
function IsAppRunning(const FileName: string): Boolean; 
var 
    FWMIService: Variant; 
    FSWbemLocator: Variant; 
    FWbemObjectSet: Variant; 
begin 
    Result := false; 
    FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator'); 
    FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', ''); 
    FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName])); 
    Result := (FWbemObjectSet.Count > 0); 
    FWbemObjectSet := Unassigned; 
    FWMIService := Unassigned; 
    FSWbemLocator := Unassigned; 
end; 

function InitializeSetup: boolean; 
begin 
    Result := not IsAppRunning('notepad.exe'); 
    if not Result then 
    MsgBox('notepad.exe is running. Please close the application before running the installer ', mbError, MB_OK); 
end; 
+3

¿En qué se diferencia esto de ['this post'] (http://stackoverflow.com/a/24181158/960757)? Bueno, lo es. No necesita asignar 'Sin asignar' a los objetos ya que serán * liberados * cuando salgan del alcance de la función. Y debe verificar la asignación después de ejecutar la consulta ('VarIsNull' en la otra publicación). Entonces, la otra publicación es un poco más corta y más precisa. – TLama

Cuestiones relacionadas