4

我读了几篇关于如何检查一个进程是否从另一个进程退出的帖子(我意识到有些人在这里迷上了语义,但只是幽默我),我试图实现它,但遇到了错误代码 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。

提前感谢您的帮助。

4

3 回答 3

4

传递给GetExitCodeProcess的句柄需要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 running\n";
        }
        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 running\n";
        }
        else
        {
            std::cout << "exit code=" << exit_code << "\n";
        }
    }
    else
    {
        std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
    }

    return 0;
}
于 2012-01-17T16:43:38.547 回答
1

OpenProcesstoken 需要 PROCESS_QUERY_INFORMATION 您正在打开只有 SYNCHRONIZE 访问权限的进程。看看你是否添加| PROCESS_QUERY_INFORMATION 它是否有效。

于 2012-01-17T16:35:47.410 回答
1

如果您只是希望 P2 在 P1 退出时做某事,还有另一种可能更简单的方法:让 P1 创建一个管道并让 P2 继承该管道的句柄。在 P2 中,从管道执行读取。当 P2 的调用ReadFile返回错误时ERROR_BROKEN_PIPE,P1 已退出。

于 2012-01-17T16:41:50.217 回答