C++ Windows - 如何从其 PID 获取进程路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1933113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:38:06  来源:igfitidea点击:

C++ Windows - How to get process path from its PID

c++windows

提问by Shante

How can I retrieve a process's fully-qualified path from its PID using C++ on Windows?

如何在 Windows 上使用 C++ 从进程的 PID 中检索进程的完全限定路径?

回答by Emerick Rogul

Call OpenProcessto get a handle to the process associated with your PID. Once you have a handle to the process, call GetModuleFileNameExto get its fully-qualified path. Don't forget to call CloseHandlewhen you're finished using the process handle.

调用OpenProcess以获取与您的 PID 关联的进程的句柄。一旦您掌握了流程的句柄,请调用GetModuleFileNameEx以获取其完全限定的路径。CloseHandle使用完进程句柄后不要忘记调用。

Here's a sample program that performs the required calls (replace 1234 with your PID):

这是一个执行所需调用的示例程序(用您的 PID 替换 1234):

#include <windows.h>
#include <psapi.h> // For access to GetModuleFileNameEx
#include <tchar.h>

#include <iostream>

using namespace std;

#ifdef _UNICODE
  #define tcout wcout
  #define tcerr wcerr
#else
  #define tcout cout
  #define tcerr cerr
#endif

int _tmain(int argc, TCHAR * argv[])
{
  HANDLE processHandle = NULL;
  TCHAR filename[MAX_PATH];

  processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, 1234);
  if (processHandle != NULL) {
    if (GetModuleFileNameEx(processHandle, NULL, filename, MAX_PATH) == 0) {
      tcerr << "Failed to get module filename." << endl;
    } else {
      tcout << "Module filename is: " << filename << endl;
    }
    CloseHandle(processHandle);
  } else {
    tcerr << "Failed to open process." << endl;
  }

  return 0;
}

回答by Steven Spark

Some notes to Emerick Rogul's solution:

Emerick Rogul 解决方案的一些说明:

Don't forget to add 'psapi.lib' to linker (additional dependencies).

不要忘记将“psapi.lib”添加到链接器(附加依赖项)。

I also changed PROCESS_ALL_ACCESSto PROCESS_QUERY_INFORMATION | PROCESS_VM_READbecause I got:

我也改PROCESS_ALL_ACCESSPROCESS_QUERY_INFORMATION | PROCESS_VM_READ,因为我得到了:

Failed to open process.

无法打开进程。

If it's compiled as a 32 bit application it will fail to get the name of 64 bit processes ("Failed to get module filename.")

如果它被编译为 32 位应用程序,它将无法获取 64 位进程的名称(“无法获取模块文件名。”)

回答by Ion Todirel

Have you tried QueryFullProcessImageName?

你试过QueryFullProcessImageName吗?

回答by Nathan Moinvaziri

I didn't have very much luck with GetModuleFileNameExand QueryFullProcessImageNameis only available on Vista or higher. I was however able to get the path for a process by using GetProcessImageFilename. It returns the windows kernel path but you can use QueryDosDeviceto compare the device path returned by GetProcessImageFilenamewith its proper drive path.

我对GetModuleFileNameEx 的运气不太好,而且QueryFullProcessImageName仅在 Vista 或更高版本上可用。但是,我能够通过使用GetProcessImageFilename获取进程的路径。它返回 Windows 内核路径,但您可以使用QueryDosDevice将返回的设备路径GetProcessImageFilename与其正确的驱动器路径进行比较。

This page shows how to normalize an windows kernel path returned by GetProcessImageFilename(see NormalizeNTPathfunction):

此页面显示了如何规范化由GetProcessImageFilename(请参阅NormalizeNTPath函数)返回的 Windows 内核路径:

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c48bcfb3-5326-479b-8c95-81dc742292ab/

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c48bcfb3-5326-479b-8c95-81dc742292ab/

回答by Khachatur

Sometimes GetModuleFileNameExreturns the 299 error code (I don't know why)

有时会GetModuleFileNameEx返回299错误代码(不知道为什么)

The only method that works for all versions of Windows, including XP is in Nathan Moinvaziri answer:

适用于所有 Windows 版本(包括 XP)的唯一方法是 Nathan Moinvaziri 的答案:

check the provided url:

检查提供的网址:

Windows API to Get a Full Process Path

获取完整进程路径的 Windows API