ktsu.RunCommand 1.4.3

Prefix Reserved
dotnet add package ktsu.RunCommand --version 1.4.3
                    
NuGet\Install-Package ktsu.RunCommand -Version 1.4.3
                    
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="ktsu.RunCommand" Version="1.4.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ktsu.RunCommand" Version="1.4.3" />
                    
Directory.Packages.props
<PackageReference Include="ktsu.RunCommand" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ktsu.RunCommand --version 1.4.3
                    
#r "nuget: ktsu.RunCommand, 1.4.3"
                    
#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.
#:package ktsu.RunCommand@1.4.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ktsu.RunCommand&version=1.4.3
                    
Install as a Cake Addin
#tool nuget:?package=ktsu.RunCommand&version=1.4.3
                    
Install as a Cake Tool

ktsu.RunCommand

A library that provides an easy way to execute a shell command and handle the output via delegates. It supports both synchronous and asynchronous execution with customizable output handling.

License

NuGet Version NuGet Version NuGet Downloads

GitHub commit activity GitHub contributors GitHub Actions Workflow Status

Installation

To install RunCommand, you can use the .NET CLI:

dotnet add package ktsu.RunCommand

Or you can use the NuGet Package Manager in Visual Studio to search for and install the ktsu.RunCommand package.

Usage

Basic Execution

The simplest way to execute a command is to use the Execute method. All methods return the process exit code:

using ktsu.RunCommand;

class Program
{
    static void Main()
    {
        int exitCode = RunCommand.Execute("echo Hello World!");

        if (exitCode == 0)
        {
            Console.WriteLine("Command executed successfully!");
        }
        else
        {
            Console.WriteLine($"Command failed with exit code: {exitCode}");
        }
    }
}

Custom Output Handling

To handle the output of the command, you can provide delegates to the OutputHandler class:

using ktsu.RunCommand;

class Program
{
    static void Main()
    {
        int exitCode = RunCommand.Execute(
            command: "echo Hello World!",
            outputHandler: new(
                onStandardOutput: Console.Write,
                onStandardError: Console.Write
            )
        );

        Console.WriteLine($"Process exited with code: {exitCode}");
    }
}

NOTE: When using the default OutputHandler, the delegates will receive undelimited chunks of output. This gives you the flexibility to receive exactly the output the command produces, including whitespace and non-printable characters, and handle it as you see fit.

Line-by-Line Output Handling

If you prefer to handle the output line by line, you can use the LineOutputHandler class:

using ktsu.RunCommand;

class Program
{
    static void Main()
    {
        int exitCode = RunCommand.Execute(
            command: "echo Hello World!",
            outputHandler: new LineOutputHandler(
                onStandardOutput: line => Console.WriteLine($"Output: {line}"),
                onStandardError: line => Console.WriteLine($"Error: {line}")
            )
        );

        Console.WriteLine($"Process exited with code: {exitCode}");
    }
}

Asynchronous Execution

All of the above examples can be executed asynchronously by using the ExecuteAsync method:

using ktsu.RunCommand;

class Program
{
    static async Task Main()
    {
        int exitCode = await RunCommand.ExecuteAsync("echo Hello World!");

        if (exitCode == 0)
        {
            Console.WriteLine("Command executed successfully!");
        }
        else
        {
            Console.WriteLine($"Command failed with exit code: {exitCode}");
        }
    }
}

Elevation (Windows)

If you need to run a command with elevated privileges, pass Elevation.Elevated. On Windows this launches the process with the runas verb, which triggers a UAC prompt:

using ktsu.RunCommand;

class Program
{
    static void Main()
    {
        int exitCode = RunCommand.Execute("powershell -Command \"Get-Service\"", Elevation.Elevated);

        Console.WriteLine($"Process exited with code: {exitCode}");
    }
}

NOTE: Output redirection is incompatible with runas, so an OutputHandler passed alongside Elevation.Elevated will not be invoked. You still get the process exit code.

On non-Windows platforms Elevation.Elevated is a no-op — prefix your command with sudo yourself if you need elevation there.

Encoding

By default, the library uses the UTF-8 encoding for the input and output streams. If you need to use a different encoding, you can specify it in the OutputHandler or LineOutputHandler constructor:

using System.Text;
using ktsu.RunCommand;

class Program
{
    static void Main()
    {
        int exitCode = RunCommand.Execute(
            command: "echo Hello World!",
            outputHandler: new(
                onStandardOutput: Console.Write,
                onStandardError: Console.Write,
                encoding: Encoding.ASCII
            )
        );
    }
}

API Reference

RunCommand Class

  • Execute(string command): Executes a command synchronously and returns the process exit code.
  • Execute(string command, OutputHandler outputHandler): Executes a command synchronously with custom output handling and returns the process exit code.
  • Execute(string command, Elevation elevation): Executes a command synchronously at the given elevation level.
  • Execute(string command, OutputHandler outputHandler, Elevation elevation): Executes a command synchronously with custom output handling at the given elevation level.
  • ExecuteAsync(string command): Executes a command asynchronously and returns a task with the process exit code.
  • ExecuteAsync(string command, OutputHandler outputHandler): Executes a command asynchronously with custom output handling and returns a task with the process exit code.
  • ExecuteAsync(string command, Elevation elevation): Executes a command asynchronously at the given elevation level.
  • ExecuteAsync(string command, OutputHandler outputHandler, Elevation elevation): Executes a command asynchronously with custom output handling at the given elevation level.

Elevation Enum

  • Elevation.Default: Run with the current process's privileges (output is captured).

  • Elevation.Elevated: On Windows, launch via the runas verb (UAC prompt); output is not captured. No-op on non-Windows.

  • OutputHandler Class

Processes output in raw chunks:

  • OutputHandler(onStandardOutput, onStandardError): Constructor with handlers for output and error streams.

LineOutputHandler Class

Processes output line by line:

  • LineOutputHandler(onStandardOutput, onStandardError): Constructor with handlers for output and error streams.

NOTE: The OutputHandler classes receive undelimited chunks of output directly from the process stream. The LineOutputHandler buffers this output and splits it by newline characters, invoking the delegates for each complete line.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Contributing

Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.

Acknowledgements

Thanks to the .NET community and ktsu.dev contributors for their support.

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  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.  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.  net8.0 is compatible.  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.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  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 (1)

Showing the top 1 NuGet packages that depend on ktsu.RunCommand:

Package Downloads
ktsu.SvnToGit.Core

Placeholder description, a single line concise description of the project, suitable for the package description in the nuget list UI.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.3 104 5/22/2026
1.4.2 116 5/19/2026
1.4.1 118 5/14/2026
1.4.0 127 5/13/2026
1.3.6-pre.5 74 2/6/2026
1.3.6-pre.4 73 2/5/2026
1.3.6-pre.3 76 2/3/2026
1.3.6-pre.2 77 2/1/2026
1.3.6-pre.1 69 1/31/2026
1.3.5 595 1/31/2026
1.3.4 139 1/30/2026
1.3.4-pre.1 69 1/28/2026
1.3.3 137 1/28/2026
1.3.3-pre.4 172 11/24/2025
1.3.3-pre.3 137 11/23/2025
1.3.3-pre.2 127 11/23/2025
1.3.3-pre.1 128 11/23/2025
1.3.2 400 9/3/2025
1.3.2-pre.1 184 9/3/2025
1.3.1 526 6/5/2025
Loading failed

## v1.4.3 (patch)

Changes since v1.4.2:

- Bump Polyfill from 10.6.0 to 10.7.0 ([@dependabot[bot]](https://github.com/dependabot[bot]))

## v1.4.2 (patch)

Changes since v1.4.1:

- Bump Polyfill from 10.5.1 to 10.6.0 ([@dependabot[bot]](https://github.com/dependabot[bot]))

## v1.4.1 (patch)

Changes since v1.4.0:

- Bump MSTest.Sdk from 4.2.2 to 4.2.3 ([@dependabot[bot]](https://github.com/dependabot[bot]))

## v1.4.0 (minor)

Changes since v1.3.0:

- Fix overload ambiguity in tests ([@Claude](https://github.com/Claude))
- Follow-ups for elevation support ([@Claude](https://github.com/Claude))
- Use single return path in ExecuteAsync ([@Claude](https://github.com/Claude))
- Add elevation support to RunCommand ([@Claude](https://github.com/Claude))
- Add TAGS.md with NuGet package tags ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove legacy build scripts ([@matt-edmondson](https://github.com/matt-edmondson))
- Add CLAUDE.md for project guidance and documentation ([@matt-edmondson](https://github.com/matt-edmondson))
- Migrate to dotnet 10 ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Force patch ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Force patch ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package versions in Directory.Packages.props, enhance PSBuild.psm1 for coverage and release processes, and adjust .runsettings for output directory. Clean up whitespace in multiple files. ([@matt-edmondson](https://github.com/matt-edmondson))
- Update .editorconfig settings, enhance RunCommand functionality to return exit codes, and add SonarLint configuration ([@matt-edmondson](https://github.com/matt-edmondson))
- Add project configuration files and update SDK references ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove Directory.Build.props, Directory.Build.targets, and several PowerShell scripts for metadata and version management. Add copyright headers to several source files in the RunCommand namespace. ([@matt-edmondson](https://github.com/matt-edmondson))
- Update DESCRIPTION.md to clarify shell command execution support and change project SDK references to ktsu.Sdk.Lib and ktsu.Sdk.Test version 1.8.0. ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.6-pre.5 (prerelease)

Changes since v1.3.6-pre.4:

- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\update-winget-manifests.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.6-pre.4 (prerelease)

Changes since v1.3.6-pre.3:

- Sync scripts\update-winget-manifests.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync global.json ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.6-pre.3 (prerelease)

Changes since v1.3.6-pre.2:

- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync global.json ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.6-pre.2 (prerelease)

Changes since v1.3.6-pre.1:

- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync global.json ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.6-pre.1 (prerelease)

Changes since v1.3.5:

- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync global.json ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync COPYRIGHT.md ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.5 (patch)

Changes since v1.3.4:

- Add CLAUDE.md for project guidance and documentation ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.4 (patch)

Changes since v1.3.3:

- Remove .github\workflows\project.yml ([@matt-edmondson](https://github.com/matt-edmondson))
- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync global.json ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitignore ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.4-pre.1 (prerelease)

No significant changes detected since v1.3.4.

## v1.3.3 (patch)

Changes since v1.3.2:

- Migrate to dotnet 10 ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.3-pre.4 (prerelease)

Changes since v1.3.3-pre.3:

- Sync scripts\update-winget-manifests.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.3-pre.3 (prerelease)

Changes since v1.3.3-pre.2:

- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.3-pre.2 (prerelease)

Changes since v1.3.3-pre.1:

- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.3-pre.1 (prerelease)

No significant changes detected since v1.3.3.

## v1.3.2 (patch)

Changes since v1.3.1:

- [patch] Force patch ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Force patch ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package versions in Directory.Packages.props, enhance PSBuild.psm1 for coverage and release processes, and adjust .runsettings for output directory. Clean up whitespace in multiple files. ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.2-pre.1 (prerelease)

No significant changes detected since v1.3.2.

## v1.3.1 (patch)

Changes since v1.3.0:

- Update .editorconfig settings, enhance RunCommand functionality to return exit codes, and add SonarLint configuration ([@matt-edmondson](https://github.com/matt-edmondson))
- Add project configuration files and update SDK references ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove Directory.Build.props, Directory.Build.targets, and several PowerShell scripts for metadata and version management. Add copyright headers to several source files in the RunCommand namespace. ([@matt-edmondson](https://github.com/matt-edmondson))
- Update DESCRIPTION.md to clarify shell command execution support and change project SDK references to ktsu.Sdk.Lib and ktsu.Sdk.Test version 1.8.0. ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.3.1-pre.2 (prerelease)

Changes since v1.3.1-pre.1:

- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .editorconfig ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .runsettings ([@ktsu[bot]](https://github.com/ktsu[bot]))

## v1.3.1-pre.1 (prerelease)

No significant changes detected since v1.3.1.

## v1.3.0 (minor)

Changes since v1.2.0:

- Add LICENSE template ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.2.0 (minor)

Changes since v1.1.0:

- [minor] Improve Git tag retrieval in changelog and version scripts ([@matt-edmondson](https://github.com/matt-edmondson))
- Enhance RunCommand library with output handling features ([@matt-edmondson](https://github.com/matt-edmondson))

## v1.1.0 (major)

- Initial commit ([@matt-edmondson](https://github.com/matt-edmondson))