C# TreeGridView 实现进程列表

效果如图

C# TreeGridView 实现进程列表_第1张图片

 

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 实现进程列表)