2012-03-30 8 views
11

Ho letto il post seguente. Il mio codice è esattamente lo stesso, ma non funziona:Come verificare con inno-setup, se un processo è in esecuzione su Windows 2008 r2 a 64 bit?

Inno Setup Checking for running process

ho copiato l'esempio da http://www.vincenzo.net/isxkb/index.php?title=PSVince

Ma l'esempio doe non sta funziona nemmeno, anche se cambio il codice come questo:

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

Il codice restituisce sempre false (il programma non è in esecuzione, anche se è in esecuzione). Testet su Windows 2008 R2 e Windows 7

Infatti, voglio controllare, se il tomcat5.exe è in esecuzione o meno. Quindi penso di non poter lavorare con un AppMutex.

Qualche idea?

UPDATE ho visto https://code.google.com/p/psvince/source/detail?r=5 ma non riesco a trovare nessuna fatti circa la compatibilità di tale DLL.

CODICE iss Completa:

[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

chiesto anche sui [Inno newsgroup Setup] (http://news.jrsoftware.org/read/article.php?id=95589&group=jrsoftware.innosetup#95589). – Deanna

+0

Sì, è giusto. Grazie per la tua risposta usenet. Avevo già visto r5-commit di psvince, ma non sono riuscito a trovare informazioni sulla compatibilità. –

+0

Deanna Ho provato il Bugfix da r5-commit di psvince. In effetti, crea un IsModuleLoaded ("app.exe") o IsModuleLoaded2 ("app.exe") "e sembra funzionare. se lo inviassi come risposta, lo accetterò. –

risposta

0

Purtroppo psvince.dll non può interrogare a 64 bit i processi in esecuzione in base alla mia osservazione, e come io non sono il suo sviluppatore, non so come risolvere il problema lavorare su Windows x64.

La mia soluzione è quella di utilizzare una casalinga riga di comando di utilità, processviewer.exe,

http://github.com/lextm/processviewer

Questo è stato testato su Windows 7 x64 in Touch Mouse Mate

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

+0

Grazie, lo proverò. Ma l'installer e il processo sono a 32 bit. Solo il sistema operativo è a 64 bit. –

+0

Ho appena aggiornato la mia risposta. –

+0

È possibile incorporare il codice direttamente nell'installer (senza distribuire un altro eseguibile)? –

38

È può usare la WMI e lo Win32_Process.

Prova ad aggiungere questa funzione al tuo script di installazione inno.

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

Questo ha funzionato, grazie! –

+3

Vorrei poterlo votare due volte! – HelloW

+0

Qualcuno può postare del codice su come usare questa funzione? – newman

1

C'è una soluzione ancora più semplice a questo; l'utilizzo del codice suggerito da RRUZ dipende dalla tua conoscenza del percorso di installazione, che se esegui all'avvio del programma di installazione, non lo sai.

La soluzione migliore è utilizzare FindWindowByClassName. Ha un leggero prerequisito che tu abbia un modulo principale che è sempre aperto, ma puoi sempre eseguire più controlli se hai una varietà di moduli che potrebbero essere aperti. Inoltre, è necessario rendere il nome della classe il più unico possibile!

funzione Esempio:

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

Il # riferimenti di precompilazione vengono definiti in precedenza lo script di installazione ...

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

Poi nella sezione di codice, lo si chiama come segue:

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; 

Se avete bisogno di qualcosa di più complesso di così, allora avete bisogno di guardare in mutex, ma la bellezza con il codice di cui sopra è è semplice, veloce e purché abbia nomi di classe ragionevolmente unici, buono come qualsiasi altra cosa.

(Anche se è possibile che si esegua su un sistema multiutente, probabilmente questa non troverà la finestra se è nella sessione di un altro utente. Ma come ho detto, per la maggior parte delle situazioni semplici, sarebbe fine.)

+0

Penso che OP non possa usare i mutex qui da 'tomcat5. exe' non sembra un'applicazione di produzione domestica. Ma se ci fosse il modo di estendere l'applicazione, i mutex sono la soluzione migliore! In InnoSetup puoi quindi utilizzare ['CheckForMutexes'] (http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_checkformutexes), quindi sarebbe ancora più semplice del tuo codice. [+1] – TLama

1

Una soluzione semplice potrebbe essere quella di provare a eliminare il file exe. Suppongo che lo sostituirai o lo disinstallerai comunque. Se il file esiste e l'eliminazione fallisce, probabilmente è in esecuzione.

7

Non ho abbastanza punti rep per aggiungere un commento all'eccellente risposta di RRUZ, quindi aggiungerò questo qui. Assicurati di rilevare le eccezioni, altrimenti l'installazione fallirà per gli utenti che non possono accedere al servizio.

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

Ingoiare le eccezioni non è una buona pratica in quanto non si sa perché nessuna delle chiamate di funzione abbia avuto esito negativo. Per esempio, quasi sempre faccio in modo che le eccezioni vengano generate mantenendo il loro chiamante a gestirle. – TLama

+1

Naturalmente, spetta allo sviluppatore prendere l'eccezione e agire di conseguenza. Stavo solo sottolineando il fatto che quei metodi possono fallire, il che porterà l'installatore a uscire senza fare il suo lavoro. –

Problemi correlati