如何在VC++2005中使用OpenProcessToken、AdjustTokenPrivileges和GetExit



我读了几篇关于如何检查一个进程是否已从另一个进程退出的文章(我意识到有些人对这里的语义感到困惑,但只是开玩笑),我试图实现它,但到处都遇到了错误代码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。

提前感谢您的帮助。

传递给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 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已退出。

相关内容

  • 没有找到相关文章

最新更新