调用CreateToolhelp32Snapshot时th32ProcessID是否为普通进程句柄?
问题根因
你出现报错的核心原因是对CreateToolhelp32Snapshot的参数定义理解有误:该接口的第二个参数th32ProcessID要求传入的是进程ID(PID,无符号32位整数类型),而非你当前传入的进程句柄。系统将你传入的句柄值当做PID查找对应进程,找不到匹配进程就会返回错误码2(系统找不到指定文件)。
修正步骤
- 调整
CreateToolhelp32Snapshot的P/Invoke定义,将第二个参数类型修改为符合Win32 API规范的uint:
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] internal static extern IntPtr CreateToolhelp32Snapshot([In] SnapshotFlags dwFlags, [In] uint th32ProcessID);
- 新增
GetProcessId的P/Invoke定义,用于从已有的进程句柄获取对应PID:
[DllImport("kernel32.dll", SetLastError = true)] internal static extern uint GetProcessId(IntPtr hProcess);
- 修改调用逻辑,先获取PID再传入快照接口:
uint targetPid = GetProcessId(ProcessHandle); IntPtr snapshotHandle = CreateToolhelp32Snapshot(SnapshotFlags.All, targetPid); // 原有校验逻辑保持不变即可 Console.WriteLine("ProcessHandle = {0}", ProcessHandle.ToString("X")); uint flags = 0; bool result = GetHandleInformation(ProcessHandle, out flags); Console.WriteLine("Last error = {0} and handle is valid = {1}", WinErrors.GetLastWin32Error(), result); Console.WriteLine((int)snapshotHandle);
额外注意事项
- 如果你需要捕获的是当前进程的快照,
th32ProcessID可以直接传0,无需额外获取当前进程PID - 快照句柄使用完成后需要调用
CloseHandle释放,避免内核对象泄漏
内容的提问来源于stack exchange,提问作者Dennis43589y
相关产品推荐
相关产品推荐

