Windows非管理员程序如何获取所有进程路径(含特权进程)
无需提权获取管理员权限进程的方法
问题原因
Windows UAC权限隔离机制下,普通权限进程调用OpenProcess打开管理员权限进程会失败(返回NULL)。你原代码中虽能通过EnumProcesses拿到进程PID,但无法获取进程路径信息,导致统计不到目标进程。
可行方案
使用终端服务API(WTSEnumerateProcesses),这套API无需打开进程句柄,就能直接获取系统内所有进程(包括管理员权限进程)的路径信息,普通权限即可调用。
修改后的代码
#include <wtsapi32.h> #include <vector> #include <string> #pragma comment(lib, "wtsapi32.lib") int countProcess(const std::wstring& path_to_exe) { int process_count = 0; // 连接到本地终端服务器 HANDLE hServer = WTSOpenServerW((LPWSTR)L"localhost"); if (hServer == NULL) { return process_count; } PWTS_PROCESS_INFOW pProcessInfo = nullptr; DWORD dwCount = 0; // 枚举所有进程 if (WTSEnumerateProcessesW(hServer, 0, 1, &pProcessInfo, &dwCount)) { for (DWORD i = 0; i < dwCount; ++i) { // 获取进程的完整路径 WCHAR szProcessPath[MAX_PATH] = {0}; DWORD dwPathLength = MAX_PATH; if (WTSQueryProcessInformationW(hServer, pProcessInfo[i].ProcessId, WTSProcessInfoLevel::WTSSessionProcessInfoEx, reinterpret_cast<LPBYTE*>(&szProcessPath), &dwPathLength)) { std::wstring process_path(szProcessPath); // 可根据需求调整路径匹配逻辑(如忽略大小写) if (process_path == path_to_exe) { process_count++; } WTSFreeMemory(szProcessPath); } } WTSFreeMemory(pProcessInfo); } WTSCloseServer(hServer); return process_count; }
注意事项
- 需要链接
wtsapi32.lib,代码中用#pragma comment(lib, "wtsapi32.lib")实现,或在项目设置中添加依赖。 WTSEnumerateProcessesW和WTSQueryProcessInformationW为Unicode版本,确保项目使用Unicode编码(默认配置通常满足)。- 务必清理资源:调用
WTSFreeMemory释放API返回的内存,调用WTSCloseServer关闭服务器句柄,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

