2010-03-02 86 views
5

我有一個Inno安裝項目,我想檢查應用程序是否實際運行,然後卸載它。我嘗試了很多方法,但在Windows 7中運行時都會失敗。例如,使用psvince.dll檢查notepad.exe進程的以下腳本始終返回false,無論記事本是否正在運行。Inno安裝程序檢查運行過程

我在C#應用程序中使用了psvince.dll來檢查它是否可以在Windows 7下運行,並且沒有任何問題。所以我最好的猜測是安裝程序無法在啓用UAC的情況下正確運行。

[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

我有同樣的問題,但AnsiString沒有幫助我。 – 2012-03-30 10:37:57

回答

7

您使用Unicode Inno Setup嗎?如果你是,應該說

function IsModuleLoaded(modulename: AnsiString): Boolean;

因爲psvince.dll不是Unicode的dll。

此外,該示例檢查epub.exe,而不是notepad.exe。

+0

我有同樣的問題,但AnsiString沒有幫助我。 – 2012-03-30 10:38:25

+0

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

4

Inno Setup實際上有一個AppMutex指令,該指令在幫助中有記錄。實現它需要2行代碼。

在您的ISS文件的[設置]部分添加:

AppMutex=MyProgramsMutexName 

然後將應用程序的啓動過程中添加這行代碼:

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

[官方文檔](http://www.jrsoftware.org/iskb.php?mutexsessions)說,你需要兩個互斥體來檢測由其他用戶啓動的實例。 – Igor 2016-08-07 20:14:11

5

您也可以嘗試使用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

您可以使用此代碼來檢查notepad.exe是否正在運行。

[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

這與['這篇文章'](http://stackoverflow.com/a/24181158/960757)有什麼不同?嗯,是的。您不需要爲對象分配'Unassigned',因爲當它們超出函數的範圍時它們將被釋放*。在運行查詢(另一個帖子中的'VarIsNull')後,您應該檢查分配情況。所以,另一篇文章有​​點短而且更精確。 – TLama 2015-02-24 07:18:24

相關問題