【问题标题】:How to know if a process handle is ready如何知道进程句柄是否准备好
【发布时间】:2011-10-07 10:08:42
【问题描述】:

我在 c++ 中使用OpenProcess 打开一个进程,但我得到它后无法立即使用它,因为我收到“无效句柄错误”。我知道正确的句柄,因为当我在此句柄上执行 GetProcessId 时,它给了我正确的 PID。 这就是我打开进程的方式。

#include <windows.h>
#include <stdio.h>
#include <dbghelp.h>
#pragma (lib, "dbghelp.lib");

bool EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable) 
{ 
    HANDLE hToken; 
    TOKEN_PRIVILEGES    tp; 
    LUID luid; 
    bool ret; 

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ, &hToken)) 
        return FALSE; 

    if (!LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid)) 
        return FALSE; 

    tp.PrivilegeCount           = 1; 
    tp.Privileges[0].Luid       = luid; 
    tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; 

    ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); 
    CloseHandle(hToken); 

    return ret; 
}

void main()
{
    EnablePrivilege(SE_DEBUG_NAME, TRUE);

    STARTUPINFOA startInfo;
    PROCESS_INFORMATION processInfo;
    ZeroMemory( &startInfo, sizeof(startInfo) );
    startInfo.cb = sizeof(startInfo);
    ZeroMemory( &processInfo, sizeof(processInfo) );
    DWORD creationFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION;
    const char* comLine = "Some process path and name";

//     Start the child process. 
    if( CreateProcessA( NULL,   // No module name (use command line)
       (LPSTR)comLine, //argv[1],        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        creationFlags,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &startInfo,            // Pointer to STARTUPINFO structure
        &processInfo )           // Pointer to PROCESS_INFORMATION structure
     == false ) 
    {
        printf("FAIL!");
return;
    }

    SetLastError(0);
    bool ok = SymInitialize(processInfo.hProcess, NULL, true);
    int err = GetLastError();

}

由于某种原因,最后一个错误值是垃圾。
有没有办法检查进程句柄是否可以使用?

【问题讨论】:

  • 你具体想看什么?
  • 怎么称呼OpenProcess,句柄怎么办。
  • PROCESS_VM_READ 和 PROCESS_QUERY_INFORMATION 不是有效的进程创建标志。
  • 好的,我删除了它们,但没有帮助。
  • Re "由于某种原因最后一个错误值是垃圾" -- 系统将 last-error 设置为错误;它不保证不会在 not-an-error 上设置 last-error。这可能不会导致错误 => 最后一个错误是“垃圾”。

标签: c++ windows process handle


【解决方案1】:

来自问题函数的文档:

Return value

If the function succeeds, the return value is an open handle to the specified process.

这意味着如果函数成功,您已经获得了一个可用的句柄,即您要么得到它,要么没有,没有中间地带“你必须等待”它才能使用。在您的特定情况下,您的句柄可能无效,即功能失败。您是否正在检查 NULL 的返回值?你用GetLastError() 看看发生了什么吗?

【讨论】:

  • CreateProcess 返回 true,但最后一个错误 = 2 (FILE NOT FOUND)
  • 尝试打印最后一个错误之前和之后,看看它是否改变。因为 GetLastError 可能正在从另一个失败的函数返回值?
  • 另外,在您的代码中,您不使用 OpenProcess 而是使用 OpenProcessHandle - 这是失败的函数吗?
  • 不,它源自 CreateProcess。 AdjustPriviliegesToken 给出最后一个错误 1300 (NOT ALL ASSIGNED) 但我不知道它是否相关。
  • 我猜测无效句柄错误来自 SymInitialize,并表明指定的进程未处于适当的状态。如果修复创建标志没有帮助,我建议你再问一个关于如何正确使用 SymInitialize 的问题。
猜你喜欢
  • 2012-10-19
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多