C# 如何检测指定Handle是否活跃,有无可用类库或Nuget包支持?
C# 实现指定句柄搜索功能的可用方案
可用Nuget包
ProcessHacker.Native:ProcessHacker官方推出的.NET原生API封装库,直接内置了和ProcessHacker本体完全一致的句柄枚举、查询能力,无需自行编写复杂的P/Invoke逻辑,开箱即可实现跨进程句柄搜索功能。Vanara.PInvoke.NtDll:Vanara是Windows系统API的全量.NET封装项目,其中NtDll模块完整封装了NT内核层的所有公开API,你可以调用NtQuerySystemInformation方法搭配SystemHandleInformation参数枚举全局所有进程的句柄,再根据你需要的条件筛选即可,支持全版本.NET Framework和.NET Core。- 原生.NET类库:如果仅需要检测当前进程内的句柄,无需引入第三方包,直接使用
System.Diagnostics.Process和SafeHandle相关封装的接口即可实现,性能最优。
参考实现代码(基于Vanara.PInvoke.NtDll)
using Vanara.PInvoke; using System; public static class HandleDetector { /// <summary> /// 搜索系统全局范围内是否存在指定名称的句柄 /// </summary> /// <param name="targetHandleName">目标句柄的名称</param> /// <returns>是否存在目标句柄</returns> public static bool CheckTargetHandleExists(string targetHandleName) { // 调用NTAPI获取系统全量句柄列表 var systemHandles = NtDll.NtQuerySystemInformation<NtDll.SYSTEM_HANDLE_INFORMATION_EX>( NtDll.SYSTEM_INFORMATION_CLASS.SystemHandleInformation); foreach (var handleEntry in systemHandles) { try { // 打开句柄所属进程获取访问权限 using var processHandle = Kernel32.OpenProcess( Kernel32.ProcessAccess.PROCESS_DUP_HANDLE, false, handleEntry.ProcessId); if (processHandle.IsInvalid) continue; // 复制句柄到当前进程以查询名称 if (Kernel32.DuplicateHandle( processHandle, (IntPtr)handleEntry.Handle, Kernel32.GetCurrentProcess(), out var duplicatedHandle, 0, false, Kernel32.DUPLICATE_HANDLE_OPTIONS.DUPLICATE_SAME_ACCESS)) { using var safeDuplicatedHandle = new Kernel32.SafeHANDLE(duplicatedHandle, true); // 查询句柄名称 var handleName = NtDll.NtQueryObjectName(safeDuplicatedHandle); // 匹配到目标句柄,执行自定义逻辑 if (handleName.Equals(targetHandleName, StringComparison.OrdinalIgnoreCase)) { // 此处可插入你需要执行的对应操作 return true; } } } catch { // 无权限访问的系统进程句柄直接跳过即可 } } return false; } }
注意事项
- 跨进程枚举全局句柄需要程序以管理员权限运行,否则会出现部分系统进程句柄无法访问、枚举不全的问题。
- 若仅需要检测当前进程的句柄,可简化逻辑,不需要调用NTAPI枚举全局句柄,直接遍历当前进程的句柄列表即可,无需管理员权限。
内容的提问来源于stack exchange,提问作者Yuuta
相关产品推荐
相关产品推荐

