通过pid判断进程是否存在windows
Judging if a process exists by pid windows
我正在开发的功能的最初目标是简单地检查给定特定进程 ID 的 Windows 平台中的进程是否仍然存在(未终止,完全 运行) .但是,我遇到了一个奇怪的情况,即 OpenProcess()
返回 ERROR_ACCESS_DENIED
(代码:5),尽管 Process Explorer 上没有显示这样的进程。
所以我进行了搜索,发现了一个类似的问题,其中分享了一些关于我正在寻找的内容的想法。
Can OpenProcess with error code ERROR_ACCESS_DENIED be used to know if process exists?
我能够确定问题所在,但由于解决方案在处理过程的 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);
}
使用上面的代码,我能够过滤掉我之前描述的问题。但我只是觉得如果不断调用它,迭代整个进程列表似乎是一个很大的开销。有没有更好的方法来解决这类问题?任何见解将不胜感激。提前致谢。
编辑:
我知道有一种情况 一个进程不是 运行,但它的对象仍然存在 (这种情况可能是调用者没有关闭进程句柄)。我不想计算 process existing 这样的情况,因为它们实际上不是 运行。这就是为什么我对我有访问权限的进程使用 GetExitCodeProcess()
而对我没有访问权限的进程使用 tl32Snapshot
的原因。
我的假设错了吗?
Would there be a better method on approaching this type of problem?
确实如此。
使用 PID 检查进程是否存活不是解决方案 - 所以你应该回去检查你的整体设计。
只需使用进程启动时获得的句柄:
HANDLE hProcess = CreateProcess(...
这听起来好像进程不是从这个进程创建的 - 所以也许像你曾经做过的那样获取它并保留它(即,一旦找到进程就尝试存储句柄而不是继续使用 PID) .
现在您可以使用函数 GetExitCodeProcess
ala.:
进行检查
DWORD returnCode{};
if (GetExitCodeProcess(handle, &returnCode)) {
if (returnCode != STILL_ACTIVE) {
//no longer active
使用 PID 不好的原因有两个:OS 可能会使进程处于 dead 状态一段时间 and 一旦您检查了 PID,它可能已经被新进程重用(在任何正常情况下您根本无法控制它)。
至于ERROR_ACCESS_DENIED
:它根本不是一个可靠的方法来检查进程是否存在。
我正在开发的功能的最初目标是简单地检查给定特定进程 ID 的 Windows 平台中的进程是否仍然存在(未终止,完全 运行) .但是,我遇到了一个奇怪的情况,即 OpenProcess()
返回 ERROR_ACCESS_DENIED
(代码:5),尽管 Process Explorer 上没有显示这样的进程。
所以我进行了搜索,发现了一个类似的问题,其中分享了一些关于我正在寻找的内容的想法。
Can OpenProcess with error code ERROR_ACCESS_DENIED be used to know if process exists?
我能够确定问题所在,但由于解决方案在处理过程的 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);
}
使用上面的代码,我能够过滤掉我之前描述的问题。但我只是觉得如果不断调用它,迭代整个进程列表似乎是一个很大的开销。有没有更好的方法来解决这类问题?任何见解将不胜感激。提前致谢。
编辑:
我知道有一种情况 一个进程不是 运行,但它的对象仍然存在 (这种情况可能是调用者没有关闭进程句柄)。我不想计算 process existing 这样的情况,因为它们实际上不是 运行。这就是为什么我对我有访问权限的进程使用 GetExitCodeProcess()
而对我没有访问权限的进程使用 tl32Snapshot
的原因。
我的假设错了吗?
Would there be a better method on approaching this type of problem?
确实如此。
使用 PID 检查进程是否存活不是解决方案 - 所以你应该回去检查你的整体设计。
只需使用进程启动时获得的句柄:
HANDLE hProcess = CreateProcess(...
这听起来好像进程不是从这个进程创建的 - 所以也许像你曾经做过的那样获取它并保留它(即,一旦找到进程就尝试存储句柄而不是继续使用 PID) .
现在您可以使用函数 GetExitCodeProcess
ala.:
DWORD returnCode{};
if (GetExitCodeProcess(handle, &returnCode)) {
if (returnCode != STILL_ACTIVE) {
//no longer active
使用 PID 不好的原因有两个:OS 可能会使进程处于 dead 状态一段时间 and 一旦您检查了 PID,它可能已经被新进程重用(在任何正常情况下您根本无法控制它)。
至于ERROR_ACCESS_DENIED
:它根本不是一个可靠的方法来检查进程是否存在。