我正在寻找很多方法来获取.NET中的父进程,但只找到了P/Invoke方式.
这是一个解决方案.它使用p/invoke,但似乎运行良好,32或64 cpu:
////// A utility class to determine a process parent. /// [StructLayout(LayoutKind.Sequential)] public struct ParentProcessUtilities { // These members must match PROCESS_BASIC_INFORMATION internal IntPtr Reserved1; internal IntPtr PebBaseAddress; internal IntPtr Reserved2_0; internal IntPtr Reserved2_1; internal IntPtr UniqueProcessId; internal IntPtr InheritedFromUniqueProcessId; [DllImport("ntdll.dll")] private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength); ////// Gets the parent process of the current process. /// ///An instance of the Process class. public static Process GetParentProcess() { return GetParentProcess(Process.GetCurrentProcess().Handle); } ////// Gets the parent process of specified process. /// /// The process id. ///An instance of the Process class. public static Process GetParentProcess(int id) { Process process = Process.GetProcessById(id); return GetParentProcess(process.Handle); } ////// Gets the parent process of a specified process. /// /// The process handle. ///An instance of the Process class. public static Process GetParentProcess(IntPtr handle) { ParentProcessUtilities pbi = new ParentProcessUtilities(); int returnLength; int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) throw new Win32Exception(status); try { return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) { // not found return null; } } }
此代码为查找父进程对象提供了一个很好的接口,并考虑了具有相同名称的多个进程的可能性:
用法:
Console.WriteLine("ParentPid: " + Process.GetProcessById(6972).Parent().Id);
码:
public static class ProcessExtensions { private static string FindIndexedProcessName(int pid) { var processName = Process.GetProcessById(pid).ProcessName; var processesByName = Process.GetProcessesByName(processName); string processIndexdName = null; for (var index = 0; index < processesByName.Length; index++) { processIndexdName = index == 0 ? processName : processName + "#" + index; var processId = new PerformanceCounter("Process", "ID Process", processIndexdName); if ((int) processId.NextValue() == pid) { return processIndexdName; } } return processIndexdName; } private static Process FindPidFromIndexedProcessName(string indexedProcessName) { var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName); return Process.GetProcessById((int) parentId.NextValue()); } public static Process Parent(this Process process) { return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id)); } }
这条路:
public static Process GetParent(this Process process) { try { using (var query = new ManagementObjectSearcher( "SELECT * " + "FROM Win32_Process " + "WHERE ProcessId=" + process.Id)) { return query .Get() .OfType() .Select(p => Process.GetProcessById((int)(uint)p["ParentProcessId"])) .FirstOrDefault(); } } catch { return null; } }