我读了几篇关于如何检查一个进程是否已从另一个进程退出的文章(我意识到有些人对这里的语义感到困惑,但只是开玩笑),我试图实现它,但到处都遇到了错误代码5("error_ACCESS_DENIED")。
这是我的工作。
1) 进程1(P1)启动进程2并将其自己的PID写入共享存储器位置。
2) 进程2(P2)从共享存储器读取PID
3) P2用P1的PID调用OpenProcess(…)来保存一个句柄,以便以后检查。
4) P2使用P1的PID重复调用GetExitCodeProcess(…),并检查STILL_ACTIVE代码。
在上面的方法中,我一直在GetExitCodeProcess上得到ACCESS_DENIED错误。我尝试使用MSDN文档中的以下代码修改P2的权限:
HANDLE proc_h = OpenProcess(SYNCHRONIZE, FALSE, GetCurrentProcessId());
HANDLE hToken;
OpenProcessToken(proc_h, TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(NULL, lpszPrivilege, &luid );
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Enable the privilege
AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
但我在调用OpenProcessToken(…)方法时不断收到ACCESS_DENIED错误。那么,这是否表明了某种系统级的障碍?我在我的机器上有管理权限,我正在运行XP。
提前感谢您的帮助。
PROCESS_QUERY_INFORMATION
访问权限。以下操作很好:
int main(int a_argc, char** a_argv)
{
int pid = atoi(*(a_argv + 1));
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (NULL != h)
{
Sleep(2000);
DWORD exit_code;
if (FALSE == GetExitCodeProcess(h, &exit_code))
{
std::cerr << "GetExitCodeProcess() failure: " <<
GetLastError() << "n";
}
else if (STILL_ACTIVE == exit_code)
{
std::cout << "Still runningn";
}
else
{
std::cout << "exit code=" << exit_code << "n";
}
}
else
{
std::cerr << "OpenProcess() failure: " << GetLastError() << "n";
}
return 0;
}
不在GetExitCodeProcess
上轮询,而是打开带有SYNCHRONIZE
的句柄并等待其退出:
int main(int a_argc, char** a_argv)
{
int pid = atoi(*(a_argv + 1));
HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (NULL != h)
{
WaitForSingleObject(h, 5000); // Change to 'INFINITE' wait if req'd
DWORD exit_code;
if (FALSE == GetExitCodeProcess(h, &exit_code))
{
std::cerr << "GetExitCodeProcess() failure: " <<
GetLastError() << "n";
}
else if (STILL_ACTIVE == exit_code)
{
std::cout << "Still runningn";
}
else
{
std::cout << "exit code=" << exit_code << "n";
}
}
else
{
std::cerr << "OpenProcess() failure: " << GetLastError() << "n";
}
return 0;
}
OpenProcesstoken需要PROCESS_QUERY_INFORMATION如果您只使用SYNCHRONIZE访问打开进程。查看是否添加| PROCESS_QUERY_INFORMATION
(如果有效)。
如果你只想让P2在P1退出时做点什么,还有另一种方法可能更容易:让P1创建一个管道,让P2继承该管道的句柄。在P2中,执行从管道读取。当P2对ReadFile
的调用返回错误ERROR_BROKEN_PIPE
时,P1已退出。