2010-03-02 51 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

相关问题