2009-08-06 67 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