如何获取应用程序的父进程的PID

我的winform应用程序由另一个应用程序(父代)启动,我需要确定应用程序的pid,它使用c#启动我的应用程序。

WMI是在C#中执行此操作的更简单方法。 Win32_Process类具有ParentProcessId属性。 这是一个例子:

using System; using System.Management; // <=== Add Reference required!! using System.Diagnostics; class Program { public static void Main() { var myId = Process.GetCurrentProcess().Id; var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId); var search = new ManagementObjectSearcher("root\\CIMV2", query); var results = search.Get().GetEnumerator(); results.MoveNext(); var queryObj = results.Current; var parentId = (uint)queryObj["ParentProcessId"]; var parent = Process.GetProcessById((int)parentId); Console.WriteLine("I was started by {0}", parent.ProcessName); Console.ReadLine(); } } 

从Visual Studio运行时输出:

我是由devenv创办的

使用Brian R. Bondy的答案作为指导,以及PInvoke.net上的内容和一些Reflector输出,我已经制作了这个,用于LinqPad MyExtensions

 public static int ParentProcessId(this Process process) { return ParentProcessId(process.Id); } public static int ParentProcessId(int Id) { PROCESSENTRY32 pe32 = new PROCESSENTRY32{}; pe32.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32)); using(var hSnapshot = CreateToolhelp32Snapshot(SnapshotFlags.Process, (uint)Id)) { if(hSnapshot.IsInvalid) throw new Win32Exception(); if(!Process32First(hSnapshot, ref pe32)) { int errno = Marshal.GetLastWin32Error(); if(errno == ERROR_NO_MORE_FILES) return -1; throw new Win32Exception(errno); } do { if(pe32.th32ProcessID == (uint)Id) return (int)pe32.th32ParentProcessID; } while(Process32Next(hSnapshot, ref pe32)); } return -1; } private const int ERROR_NO_MORE_FILES = 0x12; [DllImport("kernel32.dll", SetLastError=true)] private static extern SafeSnapshotHandle CreateToolhelp32Snapshot(SnapshotFlags flags, uint id); [DllImport("kernel32.dll", SetLastError=true)] private static extern bool Process32First(SafeSnapshotHandle hSnapshot, ref PROCESSENTRY32 lppe); [DllImport("kernel32.dll", SetLastError=true)] private static extern bool Process32Next(SafeSnapshotHandle hSnapshot, ref PROCESSENTRY32 lppe); [Flags] private enum SnapshotFlags : uint { HeapList = 0x00000001, Process = 0x00000002, Thread = 0x00000004, Module = 0x00000008, Module32 = 0x00000010, All = (HeapList | Process | Thread | Module), Inherit = 0x80000000, NoHeaps = 0x40000000 } [StructLayout(LayoutKind.Sequential)] private struct PROCESSENTRY32 { public uint dwSize; public uint cntUsage; public uint th32ProcessID; public IntPtr th32DefaultHeapID; public uint th32ModuleID; public uint cntThreads; public uint th32ParentProcessID; public int pcPriClassBase; public uint dwFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string szExeFile; }; [SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort=true)] internal sealed class SafeSnapshotHandle : SafeHandleMinusOneIsInvalid { internal SafeSnapshotHandle() : base(true) { } [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true)] internal SafeSnapshotHandle(IntPtr handle) : base(true) { base.SetHandle(handle); } protected override bool ReleaseHandle() { return CloseHandle(base.handle); } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true, ExactSpelling=true)] private static extern bool CloseHandle(IntPtr handle); } 

如果您可以控制父应用程序,则可以修改父级以在启动进程时将其PID传递给子级。

检查CreateToolhelp32Snapshot枚举的th32ParentProcessID成员。

有关如何执行此操作的示例, 请参阅此处的post 。

由于您使用的是C#,但您需要使用DllImports。 在链接的post中,每个MSDN页面都有您需要的function。 在每个MSDN页面的底部,他们有DllImport for C#的代码。

还有一种更简单的方法只使用托管代码,但如果您拥有由不同应用程序启动的多个进程名称,则它不起作用。