C# Process Tree

The usual System.Diagnostic.Process class does not contain a reference to the parent process. This can be problematic if you want to retrieve the full process tree for a specific process.

This is a guide on how to build out a process tree by using ManagementObjectSearch and the Win32_Process info class.

For starters, I created an extension method that retrieves the children of a process.

public static class ProcessExtensions  
{
    /// <summary>
    /// Get the child processes for a given process
    /// </summary>
    /// <param name="process"></param>
    /// <returns></returns>
    public static List<Process> GetChildProcesses(this Process process)
    {
        var results = new List<Process>();

        // query the management system objects for any process that has the current
        // process listed as it's parentprocessid
        string queryText = string.Format("select processid from win32_process where parentprocessid = {0}", process.Id);
        using (var searcher = new ManagementObjectSearcher(queryText))
        {
            foreach (var obj in searcher.Get())
            {
                object data = obj.Properties["processid"].Value;
                if (data != null)
                {
                    // retrieve the process
                    var childId = Convert.ToInt32(data);
                    var childProcess = Process.GetProcessById(childId);

                    // ensure the current process is still live
                    if (childProcess != null)
                        results.Add(childProcess);
                }
            }
        }
        return results;
    }
    /// <summary>
    /// Get the Parent Process ID for a given process
    /// </summary>
    /// <param name="process"></param>
    /// <returns></returns>
    public static int? GetParentId(this Process process)
    {
        // query the management system objects
        string queryText = string.Format("select parentprocessid from win32_process where processid = {0}", process.Id);
        using (var searcher = new ManagementObjectSearcher(queryText))
        {
            foreach (var obj in searcher.Get())
            {
                object data = obj.Properties["parentprocessid"].Value;
                if (data != null)
                    return Convert.ToInt32(data);
            }
        }
        return null;
    }
}

This extension method find child processes by querying the ManagementObjectSearcher for any process that has a ParentProcessId matching the current parent process's PID. Then for each item found, it will get an instance of System.Diagnostic.Process and add it to the results if the process is still valid.

The above code also contains a bonus extension method that can retrieve the parent process ID for a given process. This shoudl round out the extension methods for Process quite nicesly.

Now that you have the children, you should be able to build a process tree by recursively traversing processes and obtaining their children.

class ProcessTree  
{
    public ProcessTree(Process process)
    {
        this.Process = process;
        InitChildren();
    }

    // Recurively load children
    void InitChildren()
    {
        this.ChildProcesses = new List<ProcessTree>();

        // retrieve the child processes
        var childProcesses = this.Process.GetChildProcesses();

        // recursively build children
        foreach (var childProcess in childProcesses)
            this.ChildProcesses.Add(new ProcessTree(childProcess));
    }

    public Process Process { get; set; }

    public List<ProcessTree> ChildProcesses { get; set; }

    public int Id { get { return Process.Id; } }

    public string ProcessName { get { return Process.ProcessName; } }

    public long Memory { get { return Process.PrivateMemorySize64; } }

}

This class takes a process in its constructor. The constructor then uses our extension method to find the child processes. It adds the children to our collection and recursively loads each child.

comments powered by Disqus