SimpleExec is a .NET library that runs external commands. It wraps System.Diagnostics.Process
to make things easier.
SimpleExec intentionally does not invoke the system shell.
By default, the command is echoed to standard error (stderr) for visibility.
Platform support: .NET Standard 2.1 and later.
using static SimpleExec.Command;
Run("foo.exe", "arg1 arg2");
Run("foo.exe");
Run("foo.exe", "arg1 arg2", "my-working-directory");
await RunAsync("foo.exe");
await RunAsync("foo.exe", "arg1 arg2", "my-working-directory");
var (standardOutput1, standardError1) = await ReadAsync("foo.exe");
var (standardOutput2, standardError2) = await ReadAsync("foo.exe", "arg1 arg2", "my-working-directory");
bool noEcho = false,
string? windowsName = null,
string? windowsArgs = null,
string? echoPrefix = null,
Action<IDictionary<string, string>>? configureEnvironment = null,
bool createNoWindow = false,
Func<int, bool>? handleExitCode = null,
CancellationToken cancellationToken = default,
If the command has a non-zero exit code, an ExitCodeException
is thrown with an int
ExitCode
property and a message in the form of:
$"The process exited with code {ExitCode}."
In the case of ReadAsync
, an ExitCodeReadException
is thrown, which inherits from ExitCodeException
, and has string
Out
and Error
properties, representing standard out (stdout) and standard error (stderr), and a message in the form of:
$@"The process exited with code {ExitCode}.
Standard Output:
{Out}
Standard Error:
{Error}"
The throwing of exceptions for specific non-zero exit codes can be suppressed by passing a delegate to handleExitCode
which returns true
when it has handled the exit code and default exit code handling should be suppressed, and returns false
otherwise. For example:
Run("ROBOCOPY", "from to", handleExitCode: code => code < 8);
Note that it may be useful to record the exit code. For example:
var exitCode = 0;
var result = Run("ROBOCOPY", "from to", handleExitCode: code => (exitCode = code) < 8);
// see https://ss64.com/nt/robocopy-exit.html
var oneOrMoreFilesCopied = exitCode & 1;
var extraFilesOrDirectoriesDetected = exitCode & 2;
var misMatchedFilesOrDirectoriesDetected = exitCode & 4;
๐
Sometimes, for whatever wonderful reasons, it's necessary to run a different command on Windows. For example, when running Yarn, some combination of mysterious factors may require that you explicitly run cmd.exe
with Yarn as an argument, rather than running Yarn directly. The optional windowsNames
and windowsArgs
parameters may be used to specify a different command name and arguments for Windows:
Run("yarn", windowsName: "cmd", windowsArgs: "/c yarn");
Run by Gregor Cresnar from the Noun Project.