public static int GetParentId(this Process process)
{
PropertyInfo? parentPropertyInfo;
try
{
// Property is available on most platforms, including Windows and Linux, but not on .NET Framework
parentPropertyInfo = typeof(Process).GetProperty("ParentProcessId", BindingFlags.Instance | BindingFlags.NonPublic);
}
catch (AmbiguousMatchException)
{
parentPropertyInfo = null;
}
if (parentPropertyInfo != null)
{
try
{
return (int)parentPropertyInfo.GetValue(process);
}
catch (TargetInvocationException ex)
{
throw ex.InnerException ?? ex;
}
}
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
// Works on any Windows platform independent from .NET version
return ProcessBasicInformation.GetParentProcessId(process);
}
throw new NotSupportedException("Your platform does not support querying the parent process id");
}
public class ProcessBasicInformation
{
// Class for native method: Do NOT add or remove fields. Do NOT change the order of the fields
private readonly IntPtr exitStatus;
private readonly IntPtr processEnvironmentBlockBaseAddress;
private readonly IntPtr affinityMask;
private readonly IntPtr basePriority;
private readonly IntPtr processId;
private readonly IntPtr parentProcessId;
public static int GetParentProcessId(Process process)
{
return FillFields(process).parentProcessId.ToInt32();
}
private static ProcessBasicInformation FillFields(Process process)
{
var processBasicInformation = new ProcessBasicInformation();
NativeMethods.NtQueryInformationProcess(process, processBasicInformation);
return processBasicInformation;
}
}
public class NativeMethods
{
public static void NtQueryInformationProcess(Process process, ProcessBasicInformation processInformation)
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
throw new NotSupportedException($"{nameof(NtQueryInformationProcess)} only works on Windows");
}
var nativeStructureSize = Marshal.SizeOf<ProcessBasicInformation>();
var status = TryNtQueryInformationProcess(process.Handle, 0, processInformation, nativeStructureSize, out var returnLength);
if (status != 0)
{
throw new Win32Exception(status);
}
if (returnLength != nativeStructureSize)
{
throw new NotSupportedException("Your Windows version does not support getting the parent process id");
}
}
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[DllImport("ntdll.dll", EntryPoint = "NtQueryInformationProcess")]
private static extern int TryNtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ProcessBasicInformation processInformation, int processInformationLength, out int returnLength);