GetProcessInformation + ProcessHandleCount 是唯一正解(Win8.1+),轻量安全无需特权;Win7及更早须用NtQueryInformationProcess手动调用ntdll;句柄非文件描述符,涵盖各类内核对象。

GetProcessInformation + ProcessHandleCount 是唯一正解(Win8.1+)
Windows 从 8.1 开始,GetProcessInformation 才真正支持 ProcessHandleCount 类型——这是目前最轻量、最安全、无需特权的获取方式。旧文档里写的 GetProcessHandleCount 根本不存在,连头文件都找不到声明,硬写只会编译失败或链接报 LNK2019。
实操要点:
- 必须在包含
windows.h前定义#define _WIN32_WINNT 0x0603,否则ProcessHandleCount枚举不可见 -
GetCurrentProcess()返回的伪句柄可直接传入,不需DuplicateHandle - 返回值是
DWORD,代表系统内核当前为该进程维护的句柄计数(不是句柄表大小,也不是对象引用总数) - 失败时返回 0,常见原因是系统版本低于 8.1,此时应降级走
NtQueryInformationProcess
#define _WIN32_WINNT 0x0603
#include <windows.h>
DWORD GetHandleCountWin81Plus() {
DWORD count = 0;
if (GetProcessInformation(GetCurrentProcess(), ProcessHandleCount, &count, sizeof(count))) {
return count;
}
return 0;
}
NtQueryInformationProcess 是 Win7 及更早系统的唯一选择
Windows 7、Vista、XP 没有 GetProcessInformation,只能调用未公开但稳定可用的 NtQueryInformationProcess。它不在 windows.h 中声明,需手动加载 ntdll.dll 并定义 PROCESSINFOCLASS 常量——注意:SDK 不导出 ProcessHandleCountInformation,其真实值为 (PROCESSINFOCLASS)54。
容易踩的坑:
立即学习“C++免费学习笔记(深入)”;
- 不能直接链接
ntdll.lib,必须用GetProcAddress动态获取函数地址 - 结构体
PROCESS_HANDLE_COUNT_INFORMATION需自行定义,仅含一个ULONG HandleCount字段 - 调用前建议启用
SE_DEBUG_PRIVILEGE(对非当前进程必要,当前进程可跳过) - 返回
STATUS_INFO_LENGTH_MISMATCH表示缓冲区太小,但此处只需 4 字节,一般不会触发
句柄数 ≠ 文件描述符数,别和 Linux 的 getrlimit(RLIMIT_NOFILE) 混用
Windows 没有“文件描述符上限”概念,RLIMIT_NOFILE 是 Linux 专属接口。Windows 的句柄是通用资源引用标识,涵盖文件、事件、互斥体、线程、窗口、注册表键等——打开一个文件只是产生一个句柄,但一个句柄未必对应一个文件。
这意味着:
- 监控句柄泄漏时,不能只盯着
CreateFile,也要检查CreateEvent、CreateMutex、CreateThread等所有可能生成句柄的 API - 句柄数飙高但
lsof-style 工具查不到文件,大概率是 GDI 对象、USER 对象或同步对象没释放 - 任务管理器显示的“句柄数”列,底层就是读取同一内核字段,和你代码里拿到的值一致
为什么 EnumSystemHandles 不适合实时监控?
有人想用 NtQuerySystemInformation + SystemHandleInformation 枚举全系统句柄再筛选当前进程——这在技术上可行,但完全不实用。
问题在于:
- 需要
SeDebugPrivilege权限,普通用户态程序默认没有 - 返回的是全系统句柄快照,数据量极大(几万条起),遍历耗时且易被杀软拦截
- 无法区分句柄归属进程是否已退出,存在竞态风险
- 每次调用都触发 ETW 事件,高频采集会显著拖慢系统
真正做进程资源监控,就该用 GetProcessInformation 或 NtQueryInformationProcess 这类 per-process、无副作用的轻量接口。枚举全系统句柄只适用于调试器或内核分析工具,不是常规监控手段。


















