从Windows中的进程获取完整路径

时间:2018-11-15 10:42:35

标签: c++ windows visual-studio winapi

此api出了点问题。我已经检查了返回功能。没错但什么也没输出。

HANDLE hSnapProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnapProcess, &process);
do
{
    if (process.th32ProcessID != 0)
    {
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID);
        if (hProcess != NULL) 
        {
            wchar_t filePath[MAX_PATH];
            if (!GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
            {
                std::wcout << filePath << std::endl;
            }
        }
        CloseHandle(hProcess);
    }

} while (Process32Next(hSnapProcess, &process));
CloseHandle(hSnapProcess);

2 个答案:

答案 0 :(得分:3)

在代码中可以看到两个明显的错误,通过阅读文档都可以理解。

首先,在GetModuleFileNameEx中:

  

该句柄必须具有PROCESS_QUERY_INFORMATION和PROCESS_VM_READ访问权限。

您的句柄只有PROCESS_QUERY_INFORMATION

其次,再次在GetModuleFileNameEx中:

  

如果函数成功,则返回值指定复制到缓冲区的字符串的长度。

     

如果函数失败,则返回值为零。

您的逻辑是从头到尾的。替换:

if (!GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))

if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))

答案 1 :(得分:0)

此API没什么问题,这里唯一的错误是您的代码。

文档明确指出GetModuleFileNameExW的返回值是复制到缓冲区的字符串的长度。

如果返回值为0,则函数已失败。

因此,您只需要编写以下内容:

...
if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH) != 0)
{
   // handle "success" case
}
...

顺便说一句CloseHandle(hProcess);应该在if (hProcess != NULL)块内。

带有错误检查的完整示例

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>

int main()
{
  HANDLE hSnapProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

  if (hSnapProcess != INVALID_HANDLE_VALUE)
  {
    PROCESSENTRY32 process;
    process.dwSize = sizeof(PROCESSENTRY32);
    Process32First(hSnapProcess, &process);
    do
    {
      if (process.th32ProcessID != 0)
      {
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID);
        if (hProcess != NULL)
        {
          wchar_t filePath[MAX_PATH];
          if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
          {
            std::wcout << filePath << std::endl;
          }
          else
          {
            std::wcout << L"GetModuleFileNameExW failed with error" << GetLastError() << std::endl;
          }

          CloseHandle(hProcess);
        }
      }

    } while (Process32Next(hSnapProcess, &process));

    CloseHandle(hSnapProcess);
  }
  else
  {
    std::wcout << L"CreateToolhelp32Snapshot failed with error" << GetLastError() << std::endl;
  }
}
相关问题