Windows 进程路径获取与枚举 API 详解
本文整理了 Windows 系统下用于获取进程映像路径及枚举进程的常用 API,并对比了它们的适用场景与限制。
GetModuleFileNameExW
- 官方文档:GetModuleFileNameExW
- 作用:通过进程句柄获取模块文件路径。
- 原理:进程的主执行文件(.exe)本身也被视为进程的一个模块,该函数通过查询进程的模块列表来获取路径。
- 限制:
- 需要目标进程句柄
hProcess拥有PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限(或者PROCESS_QUERY_LIMITED_INFORMATION)。 - 在某些特殊进程上可能调用失败(例如尝试获取系统内核进程的模块名)。
- 需要目标进程句柄
- 所属系列:PSAPI (Process State API)
GetProcessImageFileName
- 官方文档:GetProcessImageFileName
- 作用:检索指定进程的可执行文件名称。
- 原理:暂缺(由系统底层提供,返回进程的映像文件名称)。
- 所属系列:PSAPI (Process State API)
QueryFullProcessImageName
- 官方文档:QueryFullProcessImageName
- 作用:检索指定进程的可执行映像的完整路径。
- 原理:暂缺(从进程的进程环境块或内核对象中获取完整路径)。
- 所属系列:WinBase
PssCaptureSnapshot
- 官方文档:PssCaptureSnapshot
- 作用:捕获目标进程的快照,用于获取进程的各类信息,如进程列表、句柄、堆等。
- 原理:对目标进程的当前状态进行一次快照捕获,之后可以通过
PssQuerySnapshot等函数查询信息。 - 限制:最低支持 Windows 8.1 或 Windows Server 2012 R2。
- 所属系列:PssAPI (Process Snapshot API)
-
使用示例:
#include <Windows.h> #include <ProcessSnapshot.h> #include <stdio.h> int main() { HPSS hPssHandle = NULL; if (PssCaptureSnapshot(GetCurrentProcess(), PSS_CAPTURE_HANDLE_BASIC_INFORMATION, 0, &hPssHandle) == ERROR_SUCCESS) { PSS_PROCESS_INFORMATION pssProcess = {}; PssQuerySnapshot(hPssHandle, PSS_QUERY_PROCESS_INFORMATION, &pssProcess, sizeof(pssProcess)); // ... wprintf(L"Path: %s\n", pssProcess.ImageFileName); // ... PssFreeSnapshot(GetCurrentProcess(), hPssHandle); } return 0; }
EnumProcesses
- 官方文档:EnumProcesses
- 作用:检索系统中每个进程对象的进程标识符 (PID)。
- 原理:枚举系统维护的进程列表。
- 注意:虽然能获取到短生命周期进程的 PID,但可能无法成功打开其句柄以进行后续操作。
- 所属系列:PSAPI (Process State API)
- 使用示例:参考官方文档 枚举所有进程
CreateToolhelp32Snapshot
- 官方文档:CreateToolhelp32Snapshot
- 作用:获取指定进程以及这些进程使用的堆、模块和线程的快照。
- 原理:对当前系统的进程列表进行快照保存。
- 注意:相比其他方法,通过此快照可以获取到短生命周期进程的部分信息。
- 所属系列:Toolhelp (工具帮助函数)
- 使用示例:参考官方文档 拍摄快照并查看进程
各 API 详细对比
| API | 最低支持平台 | 获取内容 | 返回路径格式 | 所需权限 | 所属系列 | 典型使用场景 |
|---|---|---|---|---|---|---|
| GetModuleFileNameExW | Windows XP/2003 | 指定模块路径(默认主模块) | Win32 路径 | PROCESS_QUERY_INFORMATION + PROCESS_VM_READ | PSAPI | 通过已打开进程句柄获取主模块路径 |
| GetProcessImageFileName | Windows XP/2003 | 进程映像名称 | NT 路径 | PROCESS_QUERY_INFORMATION | PSAPI | 需要 NT 路径格式或更低权限要求时 |
| QueryFullProcessImageName | Windows Vista/2008 | 进程映像全名 | Win32 路径(可请求 NT) | PROCESS_QUERY_LIMITED_INFORMATION | WinBase | 现代系统首选,权限要求低 |
| PssCaptureSnapshot | Windows 8.1/2012R2 | 进程快照(含路径) | Win32 路径 | 取决于捕获标志 | PssAPI | 需要进程快照一致性,支持高版本系统 |
| EnumProcesses | Windows XP/2003 | 所有进程 PID | — | 无(但后续 OpenProcess 需权限) | PSAPI | 枚举 PID,再配合其他函数获取详细信息 |
| CreateToolhelp32Snapshot | Windows XP/2003 | 进程快照(含基本信息) | 进程名(不含路径) | 无 | Toolhelp | 枚举进程并获取进程名、PID、父进程ID等信息 |
总结: 如果您只是想获取当前运行进程的完整路径,在较新的 Windows 系统(Vista+)上,
QueryFullProcessImageName是官方推荐且权限要求较低的选择。 如果您需要枚举所有进程并获取详细信息(包括路径、父进程 ID 等),CreateToolhelp32Snapshot结合Process32First/Process32Next是更常见的做法,且无需额外权限。GetProcessImageFileName在需要 NT 格式路径(如用于驱动层或其他内核模式组件交互)时有其特定用途。PssCaptureSnapshot适用于 Windows 8.1 及以上版本,并且需要捕获更全面的进程状态(如句柄、堆信息等)时使用,能保证快照的一致性。