2010-01-06 185 views
2

我正在使用NSIS安装程序,并试图在卸载之前检查某个应用程序是否正在运行。所以,我使用kernel32::CreateMutexA来电。这里是大块:检测一个实例是否正在运行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。

+0

由于多种原因,任何数量的cmd.exe实例都可能在系统上运行 – Anders 2010-01-07 15:56:13

+0

实际上,'cmd.exe'只是一个示例。 – Anonymous 2010-01-08 09:51:57

回答

2

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

所以:

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

附:FindProcDLL.dll必须复制到/Plugins

+0

这不适用于NSIS 2.46,也在页面上记录。 – Rex 2011-12-12 11:48:37

1

您所做的只是创建一个全局名称为"cmd.exe"的互斥锁。从MSDN articleCreateMutex

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

所以,除非cmd.exe创建一个句柄这些类型的名称"cmd.exe"对象之一,这个调用会简单地创建一个使用该名称的新互斥并返回(非erronous)处理。

1

您可能使用了错误的Win32 API函数。您的CreateMutex尝试创建一个名为mutex的“something.exe”。如果没有那个名字的话就会成功,所以除非你想要检查的过程是用这个名字创建一个互斥体,否则你不会得到你想要的结果。

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

+0

Tx Idan。 这很奇怪。当我尝试使用安装程序本身(例如'my_setup.exe')时,它可以工作!但不是与另一个过程。 – Anonymous 2010-01-08 10:02:46

+0

什么工作?从你的代码示例中,如果CreateMutexA成功了,那么messagebox就会出现 - 也就是说,没有一个带有你提供的名字的命名互斥体。无论您的行为如何,这都是您尝试解决问题的错误解决方案。 – 2010-01-08 10:29:46

+0

'CreateMutexA()'成功与安装程序本身。因此,它实际上是检测安装程序是否存在正在运行的实例的正确解决方案。但正如你所说,不是任何其他过程的良好表现。 – Anonymous 2010-01-08 13:53:45

0

对于这种事情,我已经使用无论是KillProcess或查找密终止插件NSIS - 见here

文档是非常简单的,希望这样做,你需要什么 - 一个相当小的开销。

相关问题