2012-03-15 66 views
0

當有人將此代碼作爲running only a single instance of an application的解決方案低估時沒有說明他們爲什麼這樣做,所以很好奇。確保使用WINAPI的應用程序的單個實例?

int hWnd = FindWindow(null, "My Application Title"); 
if (hWnd > 0) //If found 
{ 
    Process.GetCurrentProcess().WaitForExit(600); 
    try 
    { 
     SetForegroundWindow(hWnd); //Activate it 
     ShowWindow(hWnd, 9); 
     Process.GetCurrentProcess().Kill(); 
    } 
    catch (Exception ex) 
    { 
     //write to log 
    } 
} 

//Import the FindWindow API to find our window 
[DllImport("User32.dll")] 
public static extern int FindWindow(String ClassName, String WindowName); 
//Import the SetForeground API to activate it 
[DllImport("User32.dll")] 
public static extern IntPtr SetForegroundWindow(int hWnd); 
//Import the ShowWindow API to show it 
[DllImport("User32.dll")] 
public static extern bool ShowWindow(int hWnd, int nCmdShow); 

有人可以善意地向我解釋這種方法的缺點嗎?謝謝。

+2

'Process.GetCurrentProcess()。WaitForExit' ...什麼? – SLaks 2012-03-15 19:15:43

+0

@SLaks:只是爲了測試其他實例是否正在關閉。 – 2012-03-15 19:17:13

+0

@opatachibueze:咦?不,它沒有。 – SLaks 2012-03-15 19:18:18

回答

4

因爲如果應用程序啓動兩次(意外點擊),則會有一個小時間窗口,測試將失敗。這兩個實例都可能開始,但都沒有創建窗口。

+0

嗯,有道理。這可能發生在一臺非常緩慢的PC上,我同意。 – 2012-03-15 19:19:06

+1

在任何機器上,只是不是你:)。您明確添加了極少發生的競態條件,因此應用程序將慢慢變成「您需要非常仔細地啓動的應用程序」,否則重新啓動計算機並重試「。你將無法找到你自己的機器上的理由,它永遠不會發生,當你在看...... – 2012-03-15 19:53:18

+0

lol @AlexeiLevenkov有趣的是,我有一個類似的*用戶講故事*的經驗。 – 2012-03-15 20:10:14

1

就我所能看到的缺點而言,它應該是一個簡單的解決方案過於複雜。你不需要破解windows api來強制一個api的單個實例。我想這就是爲什麼你被低估了。

如果您按照Uwe的答案中的鏈接,您會看到您可以保留在託管代碼中,除非您有某些原因必須深入挖掘,否則這應該是您的默認代碼。

+0

關於使用WINAPI究竟是*咯*錯誤?我沒有看到任何問題。 – 2012-03-15 19:25:13

+1

我沒有問題,使用Windows API,但是有託管包裝,您可以使用。我試圖得到的是,非託管代碼更加危險,需要更多的關注,那麼爲什麼要冒這個風險呢? – 2012-03-15 19:42:32