2012-03-30 12 views
11

He leído la siguiente publicación. Mi código se ve exactamente lo mismo, pero no funciona:¿Cómo verificar con inno-setup, si un proceso se está ejecutando en un windows 2008 r2 64bit?

Inno Setup Checking for running process

he copiado el ejemplo de http://www.vincenzo.net/isxkb/index.php?title=PSVince

Pero el ejemplo doe no está trabajando bien, incluso si cambio el código de la siguiente manera:

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

El código siempre devuelve falso (el programa no se está ejecutando, incluso si está ejecutándose). Testet en Windows 2008 R2 y Windows 7

De hecho, quiero comprobar si el archivo tomcat5.exe se está ejecutando o no. Entonces creo que no puedo trabajar con un AppMutex.

¿Alguna idea?

ACTUALIZACIÓN he visto https://code.google.com/p/psvince/source/detail?r=5 pero no puedo encontrar ningún hecho acerca de la compatibilidad de esa DLL.

CÓDIGO ISS completo:

[Setup] 
AppName=PSVince 
AppVerName=PSVince 1.0 
DisableProgramGroupPage=true 
DisableStartupPrompt=true 
OutputDir=. 
OutputBaseFilename=testpsvince 
Uninstallable=false 
DisableDirPage=true 
DefaultDirName={pf}\PSVince 

[Files] 
Source: psvince.dll; Flags: dontcopy 

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

function InitializeSetup(): Boolean; 
begin 
    if(IsModuleLoaded('notepad.exe')) then 
    begin 
     MsgBox('Running', mbInformation, MB_OK); 
     Result := false; 
    end 
    else 
    begin 
     MsgBox('Not running', mbInformation, MB_OK); 
     Result := true; 
    end 
end; 
+1

También se le preguntó sobre los [grupos de Inno Setup] (http://news.jrsoftware.org/read/article.php?id=95589&group=jrsoftware.innosetup#95589). – Deanna

+0

Sí, eso es correcto. Gracias por su respuesta de usenet. Ya había visto el r5-commit de psvince, pero no pude encontrar hechos sobre la compatibilidad. –

+0

Deanna Probé el Bugfix de r5-commit de psvince. De hecho, hacer un 'IsModuleLoaded ("app.exe") o IsModuleLoaded2 ("app.exe")' y parece funcionar. si lo publicaras como respuesta, lo aceptaré. –

Respuesta

0

Desafortunadamente psvince.dll no puede consultar los procesos de 64 bits que se ejecutan en base a mi observación, y como yo no soy su promotor, no sé cómo solucionarlo para trabajar en Windows x64.

Mi solución es utilizar una casera línea de comandos de utilidad, processviewer.exe,

http://github.com/lextm/processviewer

Esto ha sido probado en Windows 7 x64 en Touch Mouse Mate

http://www.lextm.com/2012/03/new-inno-setup-installer-script-samples-version-compare-running-processes/

+0

Gracias, lo probaré. Pero el instalador y el proceso son de 32 bits. Solo el sistema operativo es de 64 bits. –

+0

Acabo de actualizar mi respuesta. –

+0

¿Es posible incrustar el código directamente en el instalador (sin implementar otro ejecutable)? –

38

Usted puede usar el WMI y el Win32_Process.

Intente agregar esta función a su script de configuración ino.

function IsAppRunning(const FileName : string): Boolean; 
var 
    FSWbemLocator: Variant; 
    FWMIService : 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; 
+0

Esto funcionó, gracias! –

+3

¡Ojalá pudiera votar esto dos veces! – HelloW

+0

¿Alguien puede publicar algún código sobre cómo usar esta función? – newman

1

Hay una solución aún más simple para esto; usar el código sugerido por RRUZ depende de que usted conozca la ruta de instalación, que si ejecuta cuando el instalador se inicia, no lo sabe.

La mejor solución es utilizar FindWindowByClassName. Tiene un prerrequisito ligero de que tiene un formulario principal que siempre está abierto, pero siempre puede ejecutar varias comprobaciones si tiene una variedad de formularios que podrían estar abiertos. ¡Ni que decir tiene que debe hacer que el nombre de clase sea lo más único posible!

función Ejemplo:

function IsAppRunning(): Boolean; 
begin                 
    Result := (FindWindowByClassName('{#AppWndClassName}') <> 0) or (FindWindowByClassName('{#AltAppWndClassName}') <> 0); 
end; 

El # referencias precompilación se definen anteriormente hasta el script de instalación ...

#define AppWndClassName "TMySplashScreen" 
#define AltAppWndClassName "TMyMainForm" 

Luego, en la sección de código, que llaman de la siguiente manera:

function InitializeUninstall(): Boolean; 
begin 
    // check if application is running 
    if IsAppRunning() then 
    begin 
    MsgBox('An Instance of MyFantasticApp is already running. - Please close it and run the uninstall again.', mbError, MB_OK); 
    Result := false; 
    end 
    else 
    Result := true; 
End; 

Si necesitas algo más complejo que esto, entonces usted tiene que mirar en exclusiones mutuas, pero la belleza con el código anterior es que es simple, rápido y siempre y cuando tenga nombres de clases razonablemente únicos, como cualquier otra cosa.

(Aunque es cierto que si se ejecuta en un sistema multiusuario, entonces probablemente no encuentre la ventana si está en la sesión de otro usuario. Pero como dije, para la mayoría de las situaciones simples, esto sería bien.)

+0

Creo que OP no puede usar mutexes aquí desde 'tomcat5. exe' no suena como una aplicación de elaboración casera. Pero si hubiera la forma de extender la aplicación, ¡los mutexes son la mejor opción! En InnoSetup podría usar ['CheckForMutexes'] (http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_checkformutexes), por lo que sería incluso más simple que su código. [+1] – TLama

1

Una solución simple podría ser tratar de eliminar el archivo exe. Supongo que lo reemplazará o desinstalará de todos modos. Si el archivo existe y lo elimina, entonces probablemente se esté ejecutando.

7

No tengo suficientes puntos de representación para agregar un comentario a la excelente respuesta de RRUZ, así que solo agregaré esto aquí. Asegúrese de detectar excepciones; de lo contrario, el instalador no podrá acceder a los usuarios que no puedan acceder al servicio.

try 
     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); 
except 
end; 
+1

No es una buena práctica anotar excepciones, ya que no sabrá por qué falló alguna de las llamadas a la función. Por ejemplo, casi siempre dejo que las excepciones sean lanzadas manteniendo a su interlocutor atendiéndolas. – TLama

+1

Por supuesto, le corresponde al desarrollador detectar la excepción y actuar en consecuencia. Solo estaba señalando el hecho de que esos métodos pueden fallar, lo que llevará al instalador a salir sin hacer su trabajo. –

Cuestiones relacionadas