.NET 11 Preview - Capturing Process Output & Errors
[C#, .NET, .NET 11 Preview]
Occasionally it is necessary to run a program, typically a terminal program, and capture its output.
This is possible in .NET using the Process and ProcessStartInfo classes.
Typically you would do it like this:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
var startInfo = new ProcessStartInfo
{
FileName = "pwd",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = Process.Start(startInfo))
{
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
await process.WaitForExitAsync();
if (process.ExitCode == 0)
Log.Information(output);
else
Log.Error(error);
}
As you can see, this requires quite a bit of orchestration.
In .NET 11, this has been simplified using new methods - RunAndCaptureText and its async counterpart, RunAndCaptureTextAsync, that have been added to the Process class.
The code is as follows:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
var result = await Process.RunAndCaptureTextAsync("pwd");
if (result.ExitStatus.ExitCode == 0)
Log.Information(result.StandardOutput);
else
Log.Error(result.StandardError);
You can see here that the code is much less.
This should return something like this:

If you wanted to pass arguments to your command, you would do it like this, using the overload that takes arguments:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
var result = await Process.RunAndCaptureTextAsync("pwd", ["-l"]);
if (result.ExitStatus.ExitCode == 0)
Log.Information(result.StandardOutput);
else
Log.Error(result.StandardError);
This will return the following:

TLDR
The Process class now has new methods, RunAndCaptureText and RunAndCaptureTextAsync, for capturing output and errors from command-line/terminal applications.
The code is in my GitHub.
Happy hacking!