Cross-Platform Way to Get Parent Process ID
Asked Answered
U

2

6

Using .Net Standard, is there a cross-platform way to get a process's parent process ID?

Several SO questions and answers address how to do this in Windows-specific ways (e.g. How to get parent process in .NET in managed way), typically using either WMI's Win32_Process, PInvoke or PerformanceCounters. However, none of these work in the cross-platform world of .Net Standard.

Update

It doesn't seem like there's currently a way to do this. I've created a couple GitHub issues suggesting that related functionality be added to .Net Standard.

Unregenerate answered 7/12, 2017 at 15:7 Comment(0)
C
0

Summarizing the discussions at github, there's a point: there should be no way in netCore to get the parent process id.

I'm sad.

Concertina answered 25/7, 2019 at 16:6 Comment(0)
C
-1
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);
Costotomy answered 24/2, 2023 at 11:50 Comment(2)
This isn't what the question asked for. It's still windows specific.Rimarimas
This works on any platform. I use it every day in my Linux docker containers. Only if your .NET is too old to get the parent process id and it detects that the OS is Windows it tries to get the parent process id via a native Windows method.Bebel

© 2022 - 2024 — McMap. All rights reserved.