Processes

edit

Find an executable

string? gitPath = ExecutableFinder.GetFullExecutablePath("git");
if (gitPath is not null)
{
    Assert.True(File.Exists(gitPath));
}

ExecutableFinder.GetFullExecutablePath looks for an executable in the folders of the PATH environment variable, like a shell does, and returns its full path, or null when it is not found:

  • On Windows, a name without extension is completed with the extensions of PATHEXT (.COM, .EXE, .BAT and .CMD when it is not set), and an extensionless file is never returned. As with cmd.exe, the quotes around a PATH entry, such as "C:\Program Files\Tool", are removed, a quoted entry can contain ;, and empty entries are ignored.
  • On Linux and macOS, only files that are executable are returned.
  • When you pass a working directory, it is searched before the folders of PATH. Pass it only when the folder is trusted: a file in it would take precedence over the executable of PATH.

To run the executable, see ProcessWrapper, which uses the same lookup.

using var currentProcess = Process.GetCurrentProcess();
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux())
{
    int? parentId = currentProcess.GetParentProcessId();
    Assert.NotNull(parentId);

    using var parent = currentProcess.GetParentProcess();
    Assert.NotNull(parent);
}
MethodReturnsPlatforms
GetParentProcessIdThe id of the parent process, or null when it is unknownWindows, Linux
GetParentProcessThe parent process, or nullWindows, Linux
GetAncestorProcessIds, GetAncestorProcessesThe parent, its parent, and so onWindows
GetChildProcessesThe processes started by the processWindows
GetDescendantProcessesThe children, their children, and so onWindows
ProcessExtensions.GetProcessesEvery process, as a ProcessEntry with its id and the id of its parentWindows

On other operating systems, the Windows-only methods throw a PlatformNotSupportedException, and GetParentProcessId returns null on macOS. The Process instances these methods return must be disposed.

A process id can be reused once the process exits, so GetParentProcessId can return the id of an unrelated process when the parent has exited. GetParentProcess returns null when the parent has exited, or when the process with that id started after the child or its start time cannot be read. For the same reason, GetAncestorProcesses stops at the first ancestor that started after its child, and GetChildProcesses and GetDescendantProcesses skip the processes that exit while they are listed.