【问题标题】:OpenProcess the handle is invalid. CloseHandle not workOpenProcess 的句柄无效。关闭句柄不起作用
【发布时间】:2019-04-21 01:23:32
【问题描述】:

我不知道我的代码有什么问题。当句柄无效时,我已经设置了条件。它将关闭句柄。但这似乎行不通。此代码试图获取 processName。当我输入存在PID时。它返回进程名称。相反,当我输入不存在像 10000 这样的 PID 时。它返回句柄无效。和错误异常抛出。但是在我的代码中,我已经在无效时设置了条件。它将关闭句柄。

    std::wstring GetProcessNameById(DWORD i_processId)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
    if (hProcess != NULL)
    {
        wchar_t processFilePath[MAX_PATH];
        if (GetModuleFileNameExW(hProcess, NULL, processFilePath, MAX_PATH))
        {
            CloseHandle(hProcess);
            wchar_t *processFileName = PathFindFileNameW(processFilePath);
            return processFileName;
        }
        else
        {
            CloseHandle(hProcess);
            SystemErrorMessage();
        }
    }
    else 
    {
        CloseHandle(hProcess);
        SystemErrorMessage();
    }
}

int main()
{
std::wcout << GetProcessNameById(10000);
return 0;
}

【问题讨论】:

  • @RbMm 这就是我认为如果成功处理它将返回 processName。但是失败的时候。我不把返回到 wstring。也许是这样。
  • 我一开始没有注意到您的函数返回wstring - 因为return processFileName; 的结果是隐式转换。但是您对CloseHandle 的逻辑当然是错误的。你只需要一个电话CloseHandle,以防它不为零
  • @RbMm 我不知道你是什么意思。我删除了其他大括号。结果还是一样。并且我认为如果我在其他支架内移除。我怎么知道它是否返回无效句柄。
  • OpenProcess 返回或 0 或有效句柄。并且此句柄在开始时没有保护关闭属性。 CloseHandle 当然工作正确。不关闭手柄不起作用。你的代码不起作用
  • @RbMm 所以 0 与 c++ 中的 NULL 不同?

标签: c++ windows visual-studio winapi


【解决方案1】:

您的代码的紧凑版本使错误显而易见:

if (hProcess != NULL)
{
    // Left out for brevity
}
else 
{
    // Here, hProcess is NULL
    CloseHandle(hProcess);
    SystemErrorMessage();
}

本质上,这是在调用CloseHandle(NULL);,大概是把线程的最后一个错误代码设置为ERROR_INVALID_HANDLESystemErrorMessage() 可能会盲目调用GetLastError(不评估是否应该),如果返回的值不是ERROR_SUCCESS,则抛出异常。

要修复此问题,您需要修复逻辑错误(删除对 else 分支中的 CloseHandle 的调用,您知道 hProcess 在其中无效)。完成后,重新处理整个错误处理。它不会可靠地工作。任何时候 API 调用失败都不能盲目调用GetLastError。完成后,研究RAII idiom,这样您就不必像使用 C 语言那样编写手动清理代码了。

【讨论】:

  • 但我认为我的逻辑是正确的。作为描述 OpenProcess 返回值。 from msdn is 如果函数成功,返回值是指定进程的打开句柄。如果函数失败,则返回值为 NULL。要获取扩展错误信息,请调用 GetLastError。
  • 我不知道是否指向我的线程。如果你认为我的逻辑是错误的。我只是在条件相反但仍然相同if (hProcess == NULL) {} else {}
  • 在 else 大括号内是 getprocessname。
  • @IInspectable 请添加简短说明为什么 GetLastError 不适用于所有 win32 api。
  • @joh 如果您需要错误代码,您必须在调用失败后立即调用 GetLastError。任何介入的调用都可能更改错误代码。
猜你喜欢
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2018-09-01
  • 2019-08-23
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多