效果如图
0x01 获取进程列表,使用Win32Api规避"拒绝访问"异常
public List<AppProcess> GetAppProcesses() { IntPtr handle = NativeMethods.CreateToolhelp32Snapshot(0x2, 0); List<ProcessEntry32> list = new List<ProcessEntry32>(); List<AppProcess> applist = new List<AppProcess>(); if ((int)handle > 0) { ProcessEntry32 pe32 = new ProcessEntry32(); pe32.dwSize = (uint)Marshal.SizeOf(pe32); int bMore = NativeMethods.Process32First(handle, ref pe32); while (bMore == 1) { ProcessEntry32 pe = pe32.MarshalEx(); //排除掉[System Process] if (pe.th32ProcessID > 0) { IntPtr processHandle = NativeMethods.OpenProcess(NativeMethods.PROCESS_ALL_ACCESS, true, pe.th32ProcessID); //排除掉无法访问的 if (processHandle != IntPtr.Zero) { pe.processHandle = processHandle; list.Add(pe); } else { var err = Marshal.GetLastWin32Error(); applist.Add(new AppProcess { 进程ID = pe.th32ProcessID, 文件名 = pe.szExeFile, 父级进程ID = pe.th32ParentProcessID }); } } bMore = NativeMethods.Process32Next(handle, ref pe32); } } NativeMethods.CloseHandle(handle); foreach (ProcessEntry32 p in list) { var processHandle = p.processHandle; var winExePath = new StringBuilder(512); var len = NativeMethods.GetModuleFileNameEx(processHandle, IntPtr.Zero, winExePath, (uint)winExePath.Capacity); if (len > 0) { var path = winExePath.ToString(); var baseName = p.szExeFile; var description = ""; var manifuture = ""; try { var err = 0; var baseNameSb = new StringBuilder(128); var nameLen = NativeMethods.GetModuleBaseName(new SafeProcessHandle(processHandle, false), 0, baseNameSb, baseNameSb.Capacity); if (nameLen > 0) { baseName = baseNameSb.ToString(); } else { err = Marshal.GetLastWin32Error(); } PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int sizeInfoReturned; int queryStatus = NativeMethods.NtQueryInformationProcess(processHandle, (PROCESSINFOCLASS)0, ref pbi, Marshal.SizeOf(pbi), out sizeInfoReturned); NativeMethods.CloseHandle(processHandle); var peb = pbi.PebBaseAddress; FileVersionInfo info = FileVersionInfo.GetVersionInfo(path); description = info.FileDescription; manifuture = info.CompanyName; } catch (FileNotFoundException) { } catch (Exception ex) { } applist.Add(new AppProcess { 制造商 = manifuture, 进程ID = p.th32ProcessID, 文件名 = baseName, 自身描述 = description, 文件路径 = path, 父级进程ID = p.th32ParentProcessID > 0 ? p.th32ParentProcessID : (uint?)null }); } else { var err = Marshal.GetLastWin32Error(); Console.WriteLine("进程" + p + " 获取模块路径失败。错误代码" + err); } } return applist; }
0x02 递归将列表转为树结构
private void SetSubItems(IEnumerable<AppProcess> rootList, IEnumerable<AppProcess> plist) { foreach (var rootItem in rootList) { foreach (var item in plist) { if (item.父级进程ID == rootItem.进程ID) { rootItem.SubItems.Add(item); } } SetSubItems(rootItem.SubItems, plist); } }
0x03 递归树结构绑定到控件节点
private void SetNodes(IEnumerable<AppProcess> rootList, TreeGridNodeCollection nodes) { foreach (var item in rootList) { var node = nodes.Add(item.文件名, item.进程ID, item.文件路径, item.制造商, item.自身描述); node.ImageIndex = 0; SetNodes(item.SubItems, node.Nodes); } }
群共享获取源码 .Net软件小组 283590657