SimpleExec Documentation

repository·main·Indexed 21 days ago

https://github.com/adamralph/simple-exec

A .NET 8.0+ library that simplifies running external commands by wrapping System.Diagnostics.Process. It provides a clean API for synchronous and asynchronous execution via Run and RunAsync, and output capture via ReadAsync, without invoking the system shell. Features include environment configuration, custom exit code handling through ExitCodeException and ExitCodeReadException, and support for various argument patterns.

Tokens
1.6K
Snippets
6
Records
7
Agent score
24%

What's inside SimpleExec

  1. Quick start with SimpleExec

    main

    SimpleExec is a .NET library for running external commands by wrapping System.Diagnostics.Process. It intentionally does not invoke the system shell. To use it, import SimpleExec.Command and use the Run method.

    Requirements:

    • .NET 8.0 or later
    using static SimpleExec.Command;
    
    Run("foo", "arg1 arg2");
  2. Override default exit code handling

    main

    By default, any non-zero exit code throws an exception. If a program returns a non-zero code for a successful operation (e.g., Robocopy), you can suppress the exception by providing a delegate to the handleExitCode parameter.

    Return true from the delegate to indicate the exit code has been handled (suppressing the exception), or false to allow the default exception behavior.

    // Suppress exception for Robocopy if exit code is less than 8
    Run("ROBOCOPY", "from to", handleExitCode: code => code < 8);
    
    // Capture the exit code while suppressing the exception
    var exitCode = 0;
    Run("ROBOCOPY", "from to", handleExitCode: code => (exitCode = code) < 8);
    
    // Use the captured exit code
    var oneOrMoreFilesCopied = exitCode & 1;
  3. Execute commands with Run and RunAsync

    main

    Use Run for synchronous execution or RunAsync for asynchronous execution. By default, the command is echoed to standard output (stdout) for visibility.

    Supported argument patterns:

    • Single command string: Run("foo")
    • Command with space-separated arguments: Run("foo", "arg1 arg2")
    • Command with argument array: Run("foo", new[] { "arg1", "arg2" })
    // Synchronous
    Run("foo");
    Run("foo", "arg1 arg2");
    Run("foo", new[] { "arg1", "arg2" });
    
    // Asynchronous
    await RunAsync("foo");
    await RunAsync("foo", "arg1 arg2");
    await RunAsync("foo", new[] { "arg1", "arg2" });
  4. Capture command output with ReadAsync

    main

    Use ReadAsync when you need to capture the standard output (stdout) and standard error (stderr) of a command. It returns a tuple containing the output strings.

    var (standardOutput1, standardError1) = await ReadAsync("foo");
    var (standardOutput2, standardError2) = await ReadAsync("foo", "arg1 arg2");
    var (standardOutput3, standardError3) = await ReadAsync("foo", new[] { "arg1", "arg2" });
  5. Configure ReadAsync options

    main

    The ReadAsync method accepts the following optional parameters:

    • string workingDirectory: The directory in which to run the command.
    • Action<IDictionary<string, string?>>? configureEnvironment: A delegate to configure environment variables.
    • Func<int, bool>? handleExitCode: A delegate to suppress exception throwing for specific exit codes.
    • Encoding? encoding: The encoding to use for reading output.
    • string? standardInput: Text to pass to the command's standard input.
    • bool cancellationIgnoresProcessTree: If true, cancelling the token does not kill the process tree.
    • CancellationToken ct: A cancellation token.
    // Available parameters for ReadAsync
    string workingDirectory = "",
    Action<IDictionary<string, string?>>? configureEnvironment = null,
    Func<int, bool>? handleExitCode = null,
    Encoding? encoding = null,
    string? standardInput = null,
    bool cancellationIgnoresProcessTree = false,
    CancellationToken ct = default,
  6. Configure Run and RunAsync options

    main

    The Run and RunAsync methods accept several optional parameters to control execution environment and behavior:

    • string workingDirectory: The directory in which to run the command.
    • Action<IDictionary<string, string?>>? configureEnvironment: A delegate to configure environment variables.
    • IEnumerable<string> secrets: A collection of secrets to be handled.
    • Func<int, bool>? handleExitCode: A delegate to suppress exception throwing for specific exit codes.
    • string? echoPrefix: A prefix for the command echo.
    • bool noEcho: If true, the command is not echoed to stdout.
    • bool cancellationIgnoresProcessTree: If true, cancelling the token does not kill the process tree.
    • bool createNoWindow: If true, no console window is created.
    • CancellationToken ct: A cancellation token.
    // Available parameters for Run/RunAsync
    string workingDirectory = "",
    Action<IDictionary<string, string?>>? configureEnvironment = null,
    IEnumerable<string> secrets = null,
    Func<int, bool>? handleExitCode = null,
    string? echoPrefix = null,
    bool noEcho = false,
    bool cancellationIgnoresProcessTree = false,
    bool createNoWindow = false,
    CancellationToken ct = default,
  7. Handle command exit code exceptions

    main

    SimpleExec throws exceptions when a command returns a non-zero exit code:

    1. ExitCodeException: Thrown by Run/RunAsync. Contains an int ExitCode property. Message format: "The command exited with code {ExitCode}."
    2. ExitCodeReadException: Thrown by ReadAsync (inherits from ExitCodeException). Contains string StandardOutput and string StandardError properties. Message format includes the exit code, stdout, and stderr.