2

我正在开发 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这里)永远不会被检测到。

我错过了什么?

德克萨斯州。

4

4 回答 4

2

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

所以:

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

PS FindProcDLL.dll必须复制到/Plugins.

于 2010-01-28T15:32:14.587 回答
1

您所做的只是创建一个具有全局名称的互斥锁"cmd.exe"。来自MSDNCreateMutex文章:

如果 lpName 与现有事件、信号量、可等待计时器、作业或文件映射对象的名称匹配,则该函数将失败并且 GetLastError 函数返回 ERROR_INVALID_HANDLE。这是因为这些对象共享相同的名称空间。

因此,除非cmd.exe使用 name 为其中一种类型的对象创建句柄,否则"cmd.exe"此调用将简单地创建一个具有该名称的新互斥体并返回(非错误)句柄。

于 2010-01-06T16:51:37.660 回答
1

您可能使用了错误的 Win32 API 函数。您的 CreateMutex 尝试创建一个命名的互斥锁“something.exe”。如果没有一个具有该名称的对象,它将成功,因此除非您尝试检查的过程是创建具有该名称的互斥锁,否则您将不会得到您想要的结果。

您想要的可能是枚举所有正在运行的进程并查看您所追求的进程是否在那里。您可以使用 Win32 API 中的 ToolHelp32 执行此操作 - 请参见此处的示例。我不知道将其转换为“纯”NSIS 有多容易,因此您可能想要编写一个 DLL 插件,或者检查 NSIS 社区中是否存在现有的解决方案。

于 2010-01-06T17:01:20.633 回答
0

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

文档非常简单,希望这能满足您的需求 - 开销相当小。

于 2010-01-06T17:21:46.957 回答