2009-08-06 87 views
4

我需要檢查一個具有給定HANDLE的進程是否仍在運行,我試圖用下面的代碼來完成它,但是它總是返回第二個返回false,即使進程正在運行。檢測一個進程是否仍在運行

bool isProcessRunning(HANDLE process) 
{ 
    if(process == INVALID_HANDLE_VALUE)return false; 

    DWORD exitCode; 
    if(GetExitCodeProcess(process, &exitCode) != 0) 
     return false;//always returns here 

    return GetLastError() == STILL_ACTIVE;//still running 
} 

回答

6

您可以通過使用

bool isProcessRunning(HANDLE process) 
{ 
    return WaitForSingleObject(process, 0) == WAIT_TIMEOUT; 
} 
+0

只需要添加一個檢查對INVALID_HANDLE_VALUE因爲報告該進程正在運行當它甚至不是有效的:) – 2009-08-06 12:01:04

+0

像WaitForSingleObject這樣的API如果你有一個進程句柄是開放的,即使它終止了,也不應該返回INVALID_HANDLE_VALUE。句柄和底層對象必須保持打開狀態,直到由引用進程明確關閉(或終止這些進程)。你確定你沒有試圖在進程ID上調用它,而不是一個句柄? – 2009-08-07 20:22:18

+0

我的意思是在WaitForSingleObject之前進行檢查,如果進程尚未創建,所以句柄仍處於我初始化的值,即INVALID_HANDLE_VALUE,因爲將INVALID_HANDLE_VALUE傳遞給WaitForSingleObject總是超時(即INVALID_HANDLE_VALUEis從不它似乎是一個信號狀態)。 – 2009-08-13 19:05:01

0

您可以使用EnumProcesses()來獲取在Windows上運行的所有進程。 喜歡的東西:

bool IsProcessRunning(int pid) 
{ 
unsigned long processes[2048]; 
unsigned long num_proc = 0; 
unsigned long needed = 0; 

    // assume that 2048 processes are enought 
    if (EnumProcesses(processes, sizeof(processes), &needed)) 
    num_proc = needed/sizeof(DWORD); 

    for (int i = 0; i < num_proc; i++) 
    if (processes[i] == pid) 
     return true; 

    return false; 
} 
+0

@gimpf無論它有多複雜,它仍然是有用的。 – KymikoLoco 2015-10-16 21:21:40

+0

雖然效率很低,並且因爲它使用進程ID而不是句柄,但受到內在競爭條件的限制。 *可能*有用,我想,但可能只在邊緣情況下。 – 2017-08-03 21:07:02

1

我知道這是有點晚了,但你的代碼應該這樣寫的,如果你想你所期望的結果。

bool isProcessRunning(HANDLE process) 
{  
    DWORD exitCodeOut; 

    // GetExitCodeProcess returns zero on failure 
    if(GetExitCodeProcess(process, &exitCodeOut) == 0) 
    { 
     // Optionally get the error 
     // DWORD error = GetLastError(); 
     return false; 
    } 
    // Return if the process is still active 
    return exitCodeOut == STILL_ACTIVE; 
} 

如果你只有進程ID(PID),這個片段將工作(沒有錯誤檢查):

bool isProcessRunning(DWORD processID) 
{  
    if(HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID)) 
    { 
     DWORD exitCodeOut; 
     // GetExitCodeProcess returns zero on failure 
     if(GetExitCodeProcess(process, &exitCodeOut) != 0) 
     { 
      // Return if the process is still active 
      return exitCodeOut == STILL_ACTIVE; 
     } 
    } 
    return false; 
} 
+0

應該避免使用此方法,因爲可以爲退出的進程獲取STILL_ACTIVE。 (這是一個有效的退出代碼。) – 2017-08-03 20:53:49

+0

@HarryJohnston當且僅當進程使用259作爲退出代碼時,才正確? Microsoft建議不要將此用作錯誤代碼。由於我正在檢查的過程沒有機會返回259(正如我寫的那樣),所以完全可以接受使用退出代碼。這看起來像是一個怪物,只有當你檢查你沒有權力的進程的退出代碼時才適用。 (然而,知道並意識到這一點很好) – KymikoLoco 2017-08-03 22:00:00

+0

在這種特殊情況下,這種方法*可能是可以接受的。 OP沒有說他們檢查的過程是否是他們自己的代碼,但你的答案也沒有說明這是一個要求。 – 2017-08-03 22:14:01

相關問題