In yesterday’s post, “.NET 11 Preview - Capturing Process Output & Errors”, we looked at how .NET 11 simplifies starting a process and capturing its output.

Today we will look at another scenario - where we want to simply capture the status of a Process upon its exit.

Currently, the standard way to do it is like this:

First, we set up our logging with Serilog:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

Then our code will look like this:

var startInfo = new ProcessStartInfo
{
    FileName = "pwd",
    Arguments = "",
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true
};

using (var process = Process.Start(startInfo))
{
    await process.WaitForExitAsync();

    if (process.ExitCode == 0)
        Log.Information("Success!");

    else
        Log.Error("Failed!");
}

Here, we are using the Process and ProcessStartInfo classes, and then examining the ExitCode of the returned Process.

This has been further simplified in .NET 11 by the introduction of a new method, RunAsync, as well as its synchronous counterpart, Run.

The code now looks like this:

var result = await Process.RunAsync("pwd");
if (result.ExitCode == 0)
    Log.Information("Success");
else
    Log.Error("Failure");

If the process you want to run has arguments, there is an overload that accepts them as an IList of strings.

var result = await Process.RunAsync("pwd", ["-L"]);
if (result.ExitCode == 0)
    Log.Information("Success");
else
    Log.Error("Failure");

Unlike the Start method, this returns a ProcessExitStatus directly that you can examine for success or failure.

TLDR

Running a process and capturing its result has been simplified in .NET 11 with the Run and RunAsync methods.

The code is in my GitHub.

Happy hacking!