2012-03-30 15 views
11

Przeczytałem następujący wpis. Mój kod wygląda dokładnie tak samo, ale nie działa:Jak sprawdzić z inno-setup, jeśli proces jest uruchomiony na Windows 2008 r2 64bit?

Inno Setup Checking for running process

skopiowałem przykład z http://www.vincenzo.net/isxkb/index.php?title=PSVince

Ale przykład Doe nie działało, nawet jeśli mogę zmienić kod tak:

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

Kod zawsze zwraca wartość false (program nie działa, nawet jeśli jest uruchomiony). Testet w Windows 2008 R2 i Windows 7

W rzeczywistości chcę sprawdzić, czy tomcat5.exe jest uruchomiony, czy nie. Więc myślę, że nie mogę pracować z AppMutex.

Wszelkie pomysły?

UPDATE Widziałem https://code.google.com/p/psvince/source/detail?r=5 Ale nie mogę znaleźć żadnych faktów na temat zgodności tego DLL.

KOD Kompletna ISS:

[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

poprosił także o Inno grup dyskusyjnych [Setup] (http://news.jrsoftware.org/read/article.php?id=95589&group=jrsoftware.innosetup#95589). – Deanna

+0

Tak, zgadza się. Dziękuję za odpowiedź usenet. Widziałem już r5-commit z psvince, ale nie mogłem znaleźć faktów na temat kompatybilności. –

+0

Deanna Próbowałem Bugfixa z r5-commit z psvince. W rzeczywistości zrób "IsModuleLoaded (" app.exe ") lub IsModuleLoaded2 (" app.exe ")" i wydaje się, że działa. jeśli napiszesz to jako odpowiedź, zaakceptuję to. –

Odpowiedz

0

Niestety psvince.dll nie może zapytać 64 bitowych procesy uruchomione na podstawie moich obserwacji, jak i Ja nie jestem jego autora, nie wiem jak to naprawić do pracy na Windows x64.

Moje obejście jest użycie domową wiersza poleceń użyteczność, processviewer.exe,

http://github.com/lextm/processviewer

został przetestowany na Windows 7 x64 w Touch Mouse Mate

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

+0

Dzięki, przetestuję to. Ale instalator i proces są 32-bitowe. Tylko system operacyjny jest 64-bitowy. –

+0

Właśnie zaktualizowałem moją odpowiedź. –

+0

Czy możliwe jest osadzenie kodu bezpośrednio w instalatorze (bez wdrażania innego pliku wykonywalnego)? –

38

Ty może korzystać z WMI i Win32_Process.

Spróbuj dodać tę funkcję do skryptu instalacyjnego 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

To działało, dziękuję! –

+3

Chciałbym móc dwa razy głosować! – HelloW

+0

Czy ktoś może opublikować kod, jak korzystać z tej funkcji? – newman

1

Jest jeszcze prostsze rozwiązanie; użycie kodu sugerowanego przez RRUZ zależy od tego, czy znasz ścieżkę instalacji, która jeśli uruchomisz ją podczas inicjowania instalatora, nie wiesz tego.

Najlepszym rozwiązaniem jest użycie FindWindowByClassName. Ma niewielki warunek wstępny, że masz główną formę, która jest zawsze otwarta, ale zawsze możesz uruchomić wiele czeków, jeśli masz wiele formularzy, które mogą być otwarte. Nie trzeba też dodawać, że nazwa klasy jest tak wyjątkowa, jak to tylko możliwe!

przykład funkcja:

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

the # odniesienia prekompilacji są zdefiniowane wcześniej się skryptu instalacyjnego ...

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

Następnie w sekcji kodu, nazwać to, co następuje:

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; 

Jeśli potrzebujesz nic bardziej złożone niż to wtedy trzeba szukać w muteksy, ale piękno z powyższego kodu jest to proste, szybkie i tak długo, jak masz dość unikalne nazwy klasowe, tak dobre, jak wszystko inne.

(Wprawdzie jeśli używasz systemu wieloużytkownikowego, to prawdopodobnie nie znajdziesz tego okna w sesji innego użytkownika, ale jak już wspomniałem, w większości prostych sytuacji dobrze.)

+0

Myślę, że OP nie może używać muteksów tutaj od 'tomcat5. exe' nie brzmi jak aplikacja do domowego parzenia. Ale jeśli byłby sposób na rozszerzenie aplikacji, muteksy są najlepszym rozwiązaniem! W InnoSetup można wtedy użyć ['CheckForMutexes'] (http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_checkformexes), więc byłoby jeszcze prostsze niż twój kod. [+1] – TLama

1

Prostym rozwiązaniem może być próba usunięcia pliku exe. Zakładam, że i tak zamierzasz go zastąpić lub odinstalować. Jeśli plik istnieje i usunięcie go nie powiedzie się, prawdopodobnie działa.

7

Nie mam wystarczającej liczby punktów rep, aby dodać komentarz do doskonałej odpowiedzi RRUZ, więc dodam to tutaj. Upewnij się, że przechwytujesz wyjątki, w przeciwnym razie instalator zakończy się niepowodzeniem dla użytkowników, którzy nie mogą uzyskać dostępu do usługi.

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

Wyjątki od połknięcia nie są dobrą praktyką, ponieważ nie wiadomo, dlaczego którekolwiek z wywołań funkcji nie powiodło się. Na przykład prawie zawsze pozwalam, aby wyjątki były odrzucane, a ich rozmówca je obsługuje. – TLama

+1

Oczywiście od dewelopera zależy wychwycenie wyjątku i podjęcie odpowiednich działań. Właśnie zwracałem uwagę na to, że metody te mogą zawieść, co prowadzi do wyjścia instalatora bez wykonywania swojej pracy. –

Powiązane problemy