標籤:
效果
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
C# TreeGridView 實現進程列表