2010-01-06 180 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

文檔是非常簡單的,希望這樣做,你需要什麼 - 一個相當小的開銷。

相關問題