使用kernel32 :: CreateMutexA检测实例是否正在运行

时间:2010-01-06 16:40:54

标签: nsis

我正在使用NSIS安装程序,并尝试在卸载之前检查某个应用程序是否正在运行。所以,我使用kernel32::CreateMutexA电话。这是块:

System::Call 'kernel32::CreateMutexA(i 0, i 0, t "cmd.exe") i .r1 ?e'
Pop $R0
StrCmp $R0 0 +3
    MessageBox MB_USERICON "The application is already running."
Abort

我把它放进un.onInit。麻烦的是,从未检测到过程(cmd.exe此处)。

我错过了什么吗?

的Tx。

4 个答案:

答案 0 :(得分:2)

我找到了一个简单的解决方案;使用FindProcDLL plugin

所以:

FindProcDLL::FindProc "cmd.exe"
Pop $R0
StrCmp $R0 0 +3
 MessageBox MB_USERICON "The application is already running." IDOK
Abort
必须将

P.S。 FindProcDLL.dll复制到/Plugins

答案 1 :(得分:1)

您所做的只是使用全局名称"cmd.exe"创建互斥锁。来自CreateMutex的{​​{3}}:

  

如果lpName与现有事件的名称匹配,则信号量为waitable   计时器,作业或文件映射对象,函数失败和   GetLastError函数返回ERROR_INVALID_HANDLE。这发生了   因为这些对象共享相同的名称空间。

因此,除非cmd.exe为名称为"cmd.exe"的其中一种对象创建句柄,否则此调用只会创建一个具有该名称的新互斥锁,并返回(非错误的)句柄

答案 2 :(得分:1)

您可能使用了错误的Win32 API函数。您的CreateMutex尝试创建一个命名的互斥锁“something.exe”。如果没有具有该名称的名称将成功,那么除非您尝试检查的过程是创建具有该名称的互斥锁,否则您将无法获得您所追求的结果。

你想要的可能是枚举所有正在运行的进程,看看你所追求的进程是否存在。您可以使用Win32 API中的ToolHelp32执行此操作 - 请参阅sample here。我不知道将它转换为'纯'NSIS是多么容易,所以你可能想编写一个DLL插件,或者检查是否有一个现有的解决方案在NSIS社区中浮动。

答案 3 :(得分:0)

对于这种事情,我使用了NSIS的KillProcess或Find-Close-Terminate插件 - 请参阅here

文档非常简单,希望这可以满足您的需求 - 只需很少的开销。