Gapotchenko.FX.Diagnostics.Process 2022.2.7

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
dotnet add package Gapotchenko.FX.Diagnostics.Process --version 2022.2.7
NuGet\Install-Package Gapotchenko.FX.Diagnostics.Process -Version 2022.2.7
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Gapotchenko.FX.Diagnostics.Process" Version="2022.2.7" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Gapotchenko.FX.Diagnostics.Process --version 2022.2.7
#r "nuget: Gapotchenko.FX.Diagnostics.Process, 2022.2.7"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Gapotchenko.FX.Diagnostics.Process as a Cake Addin
#addin nuget:?package=Gapotchenko.FX.Diagnostics.Process&version=2022.2.7

// Install Gapotchenko.FX.Diagnostics.Process as a Cake Tool
#tool nuget:?package=Gapotchenko.FX.Diagnostics.Process&version=2022.2.7

Overview

The module provides extended functionality for process manipulation.

Process Extensions

GetParent()

GetParent() is an extension method provided by Gapotchenko.FX.Diagnostics.Process module for System.Diagnostics.Process class.

What it does is returns the parent process. Or null when parent process is absent or no longer running.

EnumerateParents()

Enumerates a chain of parent processes beginning with the closest parent.

ReadEnvironmentVariables()

Reads environment variables of a process.

The functionality is achieved by reading the process environment block (PEB) at the operating system level.

For example, this is how a PATH environment variable can be retrieved from all running instances of Microsoft Visual Studio:

using Gapotchenko.FX.Diagnostics;
using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        var processes = Process.GetProcessesByName("devenv");

        if (processes.Length == 0)
            Console.WriteLine("Process with a given name not found. Please modify the code and specify the existing process name.");

        foreach (var process in processes)
        {
            Console.WriteLine();
            Console.WriteLine("Process with ID {0} has the following value of PATH environment variable:", process.Id);

            var env = process.ReadEnvironmentVariables();

            string path = env["PATH"];
            Console.WriteLine(path);
        }
    }
}

ReadArguments()

The method retrieves a set of command-line arguments specified at the process start. The functionality is achieved by reading the process environment block at the operating system level.

using Gapotchenko.FX.Diagnostics;
using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        var processes = Process.GetProcessesByName("devenv");

        if (processes.Length == 0)
            Console.WriteLine("Process with a given name not found. Please modify the code and specify the existing process name.");

        foreach (var process in processes)
        {
            Console.WriteLine(
                "Process with ID {0} was started with the following command line:",
                process.Id,
                process.ReadArguments());
        }
    }
}

ReadArgumentList()

The method retrieves a sequence of command-line arguments specified at the process start. It is similar to aforementioned ReadArguments() method but returns a sequence of command-line arguments instead of a single command line string.

This fundamental difference may be essential in multi-platform scenarios. For instance, Windows represents a command line of a process as a single string, while Unix operating systems represent the command line as a strongly-typed array of command-line arguments.

Whichever method is used the results are similar, but every method provides a higher degree of detalization for the specific operating system.

End()

Allows to end a process according to a specified mode of operation.

The End() method is interesting and a bit intricate. The stock Process class already provides a similar Kill() method which performs an immediate forceful termination of a process without giving it a chance to exit gracefully.

Depending on a kind of process being terminated, Kill() is not always suitable. For example, it may have devastating consequences if someone kills a Microsoft Visual Studio process without giving it a graceful shutdown. Lost files, potentially corrupted extensions and so on.

Meet the End() method provided by Gapotchenko.FX.Diagnostics.Process module. It allows to end a process according to a specified mode of operation. The default mode of operation is ProcessEndMode.Complete that follows a sequence presented below:

  1. Graceful techniques are tried first:
    1.1. End() method tries to close a main window of the process
    1.2. If that fails, it tries to send Ctrl+C (SIGTERM) signal
  2. Forceful techniques:
    2.1. If graceful techniques fail, End() method tries to exit the process (suitable for the current process only)
    2.2. If that fails, it kills the process (SIGKILL)

The method returns a ProcessEndMode value on completion indicating how the process was actually ended.

Let's take a look on example that tries to end all running instances of Notepad:

using Gapotchenko.FX.Diagnostics;

foreach (var process in Process.GetProcessesByName("notepad"))
{
    var result = process.End();
    Console.WriteLine(result);
}

Once there is a running Notepad app, the sample produces the following output:

Close

signifying that a Notepad process was gracefully ended by closing its main window.

Now let's repeat the experiment by launching a Notepad app again and opening its File Save dialog via menu (File → Save As...). Let's keep the File Save dialog open, and launch the example code once again.

This time the result will be different:

Kill

The Notepad process was unable to shutdown gracefully and thus was forcefully killed. Graceful shutdown was not possible because the process had an active modal dialog.

More Examples

Let's modify sample a bit:

foreach (var process in Process.GetProcessesByName("notepad"))
{
    var result = process.End();

    Console.WriteLine("PID {0}", process.Id);
    Console.WriteLine("Graceful: {0}", (result & ProcessEndMode.Graceful) != 0);
    Console.WriteLine("Forceful: {0}", (result & ProcessEndMode.Forceful) != 0);
}

Now it shows the Id of a process that was ended together with a graceful/forceful classification of the result.

What if we want to limit the End() method to only perform a graceful process termination? Let's use the End(ProcessEndMode) method overload:

foreach (var process in Process.GetProcessesByName("notepad"))
{
    var result = process.End(ProcessEndMode.Graceful);

    Console.WriteLine("PID {0}", process.Id);
    Console.WriteLine(result);
}

Now the result will only be graceful, or have ProcessEndMode.None value if a process could not be gracefully ended.

But what if we want to limit the End() method to only perform a graceful process termination via Ctrl+C (SIGINT) signal and forceful kill? No problem:

foreach (var process in Process.GetProcessesByName("notepad"))
{
    var result = process.End(ProcessEndMode.Interrupt | ProcessEndMode.Kill);

    Console.WriteLine("PID {0}", process.Id);
    Console.WriteLine(result);
}

As you can see, despite a simple-looking signature, the End(…) method gives enormous possibilities for achieving a specific goal.

EndAsync()

The method is similar to End() but has an async implementation. It can be used to efficiently handle a lot of processes in bulk.

Other Modules

Let's continue with a look at some other modules provided by Gapotchenko.FX:

Or look at the full list of modules.

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net5.0-windows7.0 is compatible.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net6.0-windows7.0 is compatible.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net7.0-windows7.0 is compatible.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 is compatible.  netcoreapp2.1 is compatible.  netcoreapp2.2 was computed.  netcoreapp3.0 is compatible.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net46 is compatible.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 is compatible.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Gapotchenko.FX.Diagnostics.Process:

Package Downloads
IoFluently.NetStandard

Package Description

Gapotchenko.FX.Profiles.Core The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Represents the Core profile of Gapotchenko.FX.

Gapotchenko.FX.Console The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

The module provides virtual terminal functionality, console traits and useful primitives for .NET console apps.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Gapotchenko.FX.Diagnostics.Process:

Repository Stars
blish-hud/Blish-HUD
A Guild Wars 2 overlay with extreme extensibility through compiled modules.
Version Downloads Last updated
2022.2.7 25,921 5/1/2022
2022.2.5 1,450 5/1/2022
2022.1.4 1,477 4/6/2022
2021.2.21 1,650 1/21/2022
2021.2.20 1,461 1/17/2022
2021.1.5 7,033 7/6/2021
2020.2.2-beta 936 11/21/2020
2020.1.15 4,853 11/5/2020
2020.1.9-beta 981 7/14/2020
2020.1.8-beta 1,003 7/14/2020
2020.1.7-beta 1,045 7/14/2020
2020.1.1-beta 1,056 2/11/2020
2019.3.7 1,831 11/4/2019
2019.2.20 1,265 8/13/2019
2019.1.151 25,641 3/30/2019