最常用方式是createtoolhelp32snapshot+process32first/next遍历查pid,需初始化dwsize,兼容性好;获取完整路径用queryfullprocessimagename配合openprocess;32位程序查64位进程需enumprocesses组合方案;受保护进程无法可靠获取名称。

直接通过 PID 获取进程名在 Windows 上不能只靠 OpenProcess,必须配合系统快照(Toolhelp)或 WMI,否则会因权限、UWP 进程隔离或 32/64 位兼容性问题失败。
用 CreateToolhelp32Snapshot + Process32First/Next 遍历查 PID
这是最常用、兼容性最好、无需额外权限的方式,适用于绝大多数桌面进程(包括 32 位进程查 64 位 PID,反之亦然,但需注意快照类型)。
- 调用
CreateToolhelp32Snapshot时传TH32CS_SNAPPROCESS,返回句柄用于后续枚举 -
PROCESSENTRY32结构体的th32ProcessID字段匹配目标 PID,szExeFile即进程名(不含路径,如"chrome.exe") - 必须初始化
dwSize成员(pe32.dwSize = sizeof(PROCESSENTRY32)),否则Process32First失败返回 0 - 若目标是 64 位系统上的 64 位进程,而你的程序是 32 位,则需用
TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS并确保使用PROCESSENTRY32W(宽字符版),否则可能漏掉部分进程
用 QueryFullProcessImageName 获取完整路径(需要进程句柄)
当需要带路径的可执行文件名(如 "C:\Program Files\Firefox\firefox.exe")时,此函数比 Toolhelp 更准确,但前提是能打开目标进程句柄。
- 先调用
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)—— 注意用PROCESS_QUERY_LIMITED_INFORMATION而非旧式PROCESS_QUERY_INFORMATION,前者权限要求更低,且支持现代保护进程(如受保护的 UWP 进程仍可能拒绝) - 再调用
QueryFullProcessImageName,传入句柄和缓冲区;推荐用MAX_PATH或动态分配(GetProcessImageFileName已废弃,不推荐) - 失败常见原因:
ERROR_ACCESS_DENIED(权限不足)、ERROR_INVALID_PARAMETER(句柄无效或缓冲区太小)、ERROR_PARTIAL_COPY(32/64 位进程互查时未用Wow64EnableWow64FsRedirection切换,但该函数本身已不推荐)
64 位系统上查 32 位进程名的陷阱
32 位程序在 WoW64 下调用 CreateToolhelp32Snapshot 默认只能看到 32 位进程,除非显式启用 64 位视图。
立即学习“C++免费学习笔记(深入)”;
- 必须链接
Dbghelp.lib并调用IsWow64Process(GetCurrentProcess(), &bIsWow64)判断自身是否为 32 位 - 若为 32 位且需查全部进程,应改用
EnumProcesses+EnumProcessModules+GetModuleBaseName组合,绕过 Toolhelp 的位数限制 -
EnumProcesses返回的是 PID 数组,对每个 PID 调用OpenProcess后用EnumProcessModules获取主模块句柄,再用GetModuleBaseName读取名称 —— 这套流程更底层,也更稳定
真正难处理的是受保护进程(如 Windows Defender、ShellExperienceHost)和某些沙箱内进程,它们即使有 PID 也无法被常规 API 读取名称;此时没有可靠绕过方式,返回空或错误是正常行为。










