CreativeCoders.ProcessUtils
6.8.0
dotnet add package CreativeCoders.ProcessUtils --version 6.8.0
NuGet\Install-Package CreativeCoders.ProcessUtils -Version 6.8.0
<PackageReference Include="CreativeCoders.ProcessUtils" Version="6.8.0" />
<PackageVersion Include="CreativeCoders.ProcessUtils" Version="6.8.0" />
<PackageReference Include="CreativeCoders.ProcessUtils" />
paket add CreativeCoders.ProcessUtils --version 6.8.0
#r "nuget: CreativeCoders.ProcessUtils, 6.8.0"
#:package CreativeCoders.ProcessUtils@6.8.0
#addin nuget:?package=CreativeCoders.ProcessUtils&version=6.8.0
#tool nuget:?package=CreativeCoders.ProcessUtils&version=6.8.0
CreativeCoders.ProcessUtils
A small .NET library for running external processes from C# code. It wraps
System.Diagnostics.Process behind a testable abstraction and adds a fluent
executor with sync/async APIs, argument placeholders, output parsing and
opt-in error handling.
Installation
dotnet add package CreativeCoders.ProcessUtils
Features
- Testable process abstraction —
IProcess/IProcessFactorywrapSystem.Diagnostics.Process - Fluent executor builder — configure file name, arguments,
ProcessStartInfoand error behavior in one chain - Sync and async execution —
Execute,ExecuteAsync,ExecuteAndReturnExitCode(Async) - Typed output parsing —
IProcessOutputParser<T>withPassThrough,SplitLinesandJson<T>parsers - Argument placeholders — substitute
{{name}}tokens from a dictionary or an object's properties - Throw-on-error mode — surface non-zero exit codes as
ProcessExecutionFailedException - DI integration — single
AddProcessUtils()registration forIServiceCollection
Usage
Register the services
using CreativeCoders.ProcessUtils;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddProcessUtils();
This registers:
IProcessFactory→DefaultProcessFactory(singleton)IProcessExecutorBuilderandIProcessExecutorBuilder<T>(transient)
Start a process directly
For low-level scenarios, inject IProcessFactory:
public class GitCaller(IProcessFactory processFactory)
{
public void ShowStatus()
{
using var process = processFactory.StartProcess("git", ["status"]);
process.WaitForExit();
}
}
Execute a process and get the exit code
IProcessExecutorBuilder provides a non-generic, fluent builder for fire-and-forget
execution:
public class Pinger(IProcessExecutorBuilder builder)
{
public int Ping(string host)
{
var executor = builder
.SetFileName("ping")
.SetArguments(["-c", "1", host])
.Build();
return executor.ExecuteAndReturnExitCode();
}
}
Async variants are available for every execution method:
var exitCode = await executor.ExecuteAndReturnExitCodeAsync();
Capture and parse output
IProcessExecutorBuilder<T> adds typed output parsing. Several parsers are
shipped in CreativeCoders.ProcessUtils.Execution.Parsers:
| Parser | Output type | Description |
|---|---|---|
PassThroughProcessOutputParser |
string |
Returns standard output as-is (used automatically when T is string) |
SplitLinesOutputParser |
string[] |
Splits standard output by line, with optional trimming and StringSplitOptions |
JsonOutputParser<T> |
T |
Deserializes standard output as JSON via System.Text.Json |
public class DotnetSdks(IProcessExecutorBuilder<string[]> builder)
{
public string[] List()
{
var executor = builder
.SetFileName("dotnet")
.SetArguments(["--list-sdks"])
.SetOutputParser<SplitLinesOutputParser>(p => p.TrimLines = true)
.Build();
return executor.Execute() ?? [];
}
}
Returning a plain string does not require an explicit parser:
var output = builder
.SetFileName("uname")
.SetArguments(["-a"])
.Build()
.Execute();
For JSON output:
var executor = builder
.SetFileName("kubectl")
.SetArguments(["get", "pods", "-o", "json"])
.SetOutputParser<JsonOutputParser<PodList>>()
.Build();
var pods = await executor.ExecuteAsync();
Argument placeholders
Arguments can contain {{name}} placeholders that are replaced at execution
time. Pass either an IDictionary<string, object?> or any object whose
properties match the placeholder names:
var executor = builder
.SetFileName("git")
.SetArguments(["clone", "{{url}}", "{{target}}"])
.Build();
executor.Execute(new Dictionary<string, object?>
{
["url"] = "https://github.com/CreativeCodersTeam/Core.git",
["target"] = "./Core"
});
executor.Execute(new { url = "https://...", target = "./Core" });
Error handling
By default the executor returns whatever exit code the process produced. Enable
ShouldThrowOnError to turn non-zero exit codes into a
ProcessExecutionFailedException that carries the captured stderr:
try
{
builder
.SetFileName("dotnet")
.SetArguments(["build", "Missing.sln"])
.ShouldThrowOnError()
.Build()
.Execute();
}
catch (ProcessExecutionFailedException ex)
{
Console.WriteLine($"Exit {ex.ExitCode}: {ex.ErrorOutput}");
}
Customizing ProcessStartInfo
For advanced scenarios (working directory, environment variables, redirection
flags) use SetupStartInfo:
builder
.SetFileName("npm")
.SetArguments(["install"])
.SetupStartInfo(info =>
{
info.WorkingDirectory = "/repo";
info.Environment["CI"] = "true";
})
.Build()
.Execute();
Accessing the underlying IProcess
The ExecuteEx family returns the underlying IProcess (non-generic) or a
ProcessExecutionResult<T> (generic) so callers can inspect exit codes,
process metadata, or read raw streams. Both results are IDisposable:
using var result = builder
.SetFileName("git")
.SetArguments(["rev-parse", "HEAD"])
.Build()
.ExecuteEx();
Console.WriteLine($"git exited with {result.ExitCode}");
API Overview
| Type | Purpose |
|---|---|
IProcess / DefaultProcess |
Testable wrapper over System.Diagnostics.Process |
IProcessFactory / DefaultProcessFactory |
Creates and starts IProcess instances |
IProcessExecutor / IProcessExecutor<T> |
High-level sync/async execution APIs |
IProcessExecutorBuilder / IProcessExecutorBuilder<T> |
Fluent builders for executors |
IProcessOutputParser<T> |
Strategy for converting standard output into T |
ProcessExecutionResult<T> |
Disposable result containing the parsed value and the IProcess |
ProcessExecutionFailedException |
Raised when ShouldThrowOnError is enabled and the process exits non-zero |
ProcessUtilsServiceCollectionExtensions.AddProcessUtils |
Registers the package's services in DI |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- CreativeCoders.Core (>= 6.8.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.8.0 | 89 | 5/16/2026 |
| 6.7.3 | 93 | 4/23/2026 |
| 6.7.2 | 89 | 4/19/2026 |
| 6.7.1 | 101 | 4/1/2026 |
| 6.7.0 | 100 | 3/2/2026 |
| 6.6.0 | 134 | 2/14/2026 |
| 6.5.0 | 108 | 2/1/2026 |
| 6.4.0 | 112 | 2/1/2026 |
| 6.3.0 | 114 | 1/31/2026 |
| 6.2.0 | 110 | 1/31/2026 |
| 6.1.0 | 106 | 1/18/2026 |
| 6.0.0 | 108 | 1/17/2026 |
| 5.11.0 | 105 | 1/11/2026 |
| 5.9.0 | 110 | 12/29/2025 |
| 5.8.0 | 105 | 12/27/2025 |
| 5.7.0 | 145 | 12/26/2025 |
| 5.6.0 | 188 | 12/25/2025 |
| 5.5.0 | 190 | 12/23/2025 |
| 5.4.0 | 150 | 12/12/2025 |
| 5.3.0 | 181 | 12/5/2025 |