通过 pid 窗口判断进程是否存在

Judging if a process exists by pid windows

本文关键字:是否 存在 进程 判断 pid 窗口 通过      更新时间:2023-10-16

我正在开发的函数的最初目标是,简单地检查给定特定进程ID的Windows平台中是否仍然存在(未终止,完全运行(。但是,我遇到了一个奇怪的情况,OpenProcess()返回ERROR_ACCESS_DENIED(代码:5(,尽管进程资源管理器上没有显示这样的进程。

所以我搜索了一下,发现了一个类似的问题,它分享了一些关于我正在寻找的东西的想法。

带有错误代码ERROR_ACCESS_DENIED的OpenProcess可以用来知道进程是否存在吗?

我能够确定问题,但由于解决方案并没有在处理过程中ERROR_ACCESS_DENIED方面提供太多信息。

无论如何,我从这个问题中得到了一些想法。这是我到目前为止的代码

HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPid);
if( hProcess == NULL )
{
dwLastError = GetLastError();
if( dwLastError == ERROR_ACCESS_DENIED )
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &processEntry))
{
while( Process32Next(hSnap, &processEntry) )
{
if (processEntry.th32ProcessID == dwPid)
{
bAliveProcess = TRUE;
break;
}
}
}
CloseHandle(hSnap);
}
}
else 
{
BOOL bExit = GetExitCodeProcess(hProcess, &dwExitCode);
if (dwExitCode == STILL_ACTIVE)
{
bAliveProcess = TRUE;
}
CloseHandle(hProcess);
}

使用上面的代码,我能够过滤掉我之前描述的问题。但我只是觉得如果不断调用整个进程列表,它似乎是一个很大的开销。有没有更好的方法来解决这类问题?任何见解将不胜感激。提前谢谢。

编辑:我知道有一种情况是进程没有运行,但它的对象仍然存在(这种情况可能是,调用方没有关闭进程句柄(。我不想将此类情况视为存在的进程,因为它们实际上并未运行。这就是为什么我对我拥有访问权限的流程使用GetExitCodeProcess(),而对我没有访问权限的流程使用tl32Snapshot。 我的假设错了吗?

有没有更好的方法来解决这类问题?

确实如此。

使用PID检查过程是否处于活动状态不是一个解决方案-因此您应该返回并检查整体设计。

只需使用进程启动时获得的句柄:

HANDLE hProcess = CreateProcess(...

听起来这个过程不是从这个过程中创建的 - 所以也许像你曾经做的那样获取它,并保留它(即,一旦找到进程,就尝试存储句柄,而不是继续使用 PID(。

现在您可以使用例如GetExitCodeProcessala. 函数进行检查:

DWORD returnCode{};
if (GetExitCodeProcess(handle, &returnCode)) {
if (returnCode != STILL_ACTIVE) {
//no longer active

使用 PID 不好的原因有两个:操作系统可能会将进程保持在状态一段时间,并且一旦您检查它,PID 可能已经重新用于新进程(在任何正常情况下您根本无法控制(。

至于ERROR_ACCESS_DENIED:检查该过程是否存在根本不是一种可靠的方法。