CliInvoke 3.0.0-beta.1
Prefix ReservedSee the version list below for details.
dotnet add package CliInvoke --version 3.0.0-beta.1
NuGet\Install-Package CliInvoke -Version 3.0.0-beta.1
<PackageReference Include="CliInvoke" Version="3.0.0-beta.1" />
<PackageVersion Include="CliInvoke" Version="3.0.0-beta.1" />
<PackageReference Include="CliInvoke" />
paket add CliInvoke --version 3.0.0-beta.1
#r "nuget: CliInvoke, 3.0.0-beta.1"
#:package CliInvoke@3.0.0-beta.1
#addin nuget:?package=CliInvoke&version=3.0.0-beta.1&prerelease
#tool nuget:?package=CliInvoke&version=3.0.0-beta.1&prerelease
CliInvoke
<img src="https://github.com/alastairlundy/CliInvoke/blob/main/.assets/icon.png" width="192" height="192" alt="CliInvoke Logo">
CliInvoke is a .NET library for interacting with Command Line Interfaces and wrapping around executables.
Launch processes, redirect standard input and output streams, await process completion, and much more.
Table of Contents
- Features
- Comparison vs Alternatives
- Installing CliInvoke
- Examples
- Middleware
- Resource Disposal
- Documentation
- Contributing to CliInvoke
- License
- Acknowledgements
Features
- Clear separation of concerns between Process Configuration Builders, Process Configuration Models, and Invokers.
- Supports .NET 10 and has few dependencies.
- Has Dependency Injection extensions to make using it a breeze.
- Support for specific specializations such as running executables or commands via Windows PowerShell or CMD on Windows <sup>1</sup>
- SourceLink support
<sup>1</sup> Specializations library distributed separately.
Comparison vs Alternatives
CliInvoke is compared against CliWrap, ProcessX, and the built-in .NET Process class across features like configuration separation, DI support, middleware, cross-platform support, and licensing.
See the full comparison table for a detailed feature-by-feature breakdown.
Installing CliInvoke
CliInvoke is available on the NuGet Gallery but can also be installed via the dotnet SDK CLI.
The package(s) to install depends on your use case:
- For use in a .NET library – Install the abstractions package, your developer users can install the Implementation and Dependency Injection packages.
- For use in a .NET app – Install the implementation package and the Dependency Injection Extensions Package
| Project type / Need | Packages to install (dotnet add package ...) | Notes |
|---|---|---|
| Library author (provide abstractions only) | CliInvoke.Core |
Only the Core (abstractions) package — consumers can choose implementations. |
| Library or app that needs concrete builders / implementations | CliInvoke.Core, CliInvoke |
Implementation package plus Core for models/abstractions. |
| Desktop or Console application (common case — use DI & convenience helpers) | CliInvoke.Core, CliInvoke, CliInvoke.Extensions |
Includes DI registration and convenience extensions for easy setup, and some Middleware implementations. |
| Any project that needs platform‑specific or shell specializations (optional) | CliInvoke.Specializations (install in addition to the packages above as needed) |
Adds Cmd/PowerShell and other specializations; include only when required. |
Links to packages
CliInvoke.Core Nuget CliInvoke Nuget CliInvoke.Extensions Nuget CliInvoke.Specializations Nuget
Supported Platforms
CliInvoke supports Windows, macOS, Linux, FreeBSD, Android, and potentially some other operating systems.
For more details see the list of supported platforms
Design Patterns & When to Use Them
CliInvoke provides three core design patterns for invoking processes (with DI + Middleware and the platform Specializations as composition paths). See PATTERNS.md for comprehensive documentation on each pattern, including a Which pattern should I use? decision tree.
CliRun– Recommended default. Beginner-friendly/quickstart entrypoint. Use for basic scripting, CI/CD tasks, or simple command execution. Zero boilerplate, optional arguments with sensible defaults. Start here if you are new to CliInvoke.IProcessInvoker– DI-centric pattern and support for end-to-end process management. Use when building applications that need testability, dependency injection integration, or custom process configuration per invocation.IExternalProcess&IExternalProcessFactory– Process-like API with DI support, rich capability, stable and predictable behaviour. Use when you need granular lifecycle control, manual start/stop sequences, or power-user scenarios similar toSystem.Diagnostics.Process.
New to CliInvoke? Start with
CliRun— it is the recommended default entry point. Reach forIProcessInvokerwhen you need DI or middleware, andIExternalProcesswhen you need process-level control. See Why CliInvoke did not copy CliWrap for the design rationale.
Examples
Beginner Friendly / Quickstart
For simple use cases, the CliRun helper provides a straightforward API to execute commands with minimal boilerplate:
using CliInvoke;
using CliInvoke.Core;
// Execute a command and get the result
ProcessResult result = await CliRun.RunAsync("dotnet", "--version");
Console.WriteLine($"Exit Code: {result.ExitCode}");
For capturing output, use RunBufferedAsync:
using CliInvoke;
using CliInvoke.Core;
// Execute and capture stdout/stderr
BufferedProcessResult result = await CliRun.RunBufferedAsync("dotnet", "--info");
Console.WriteLine(result.StandardOutput);
Console.WriteLine(result.StandardError);
CliRun is ideal for scripting, quick prototypes, and basic command execution where you don't need dependency injection or advanced configuration.
For detailed documentation on all available patterns and when to use them, see PATTERNS.md.
Advanced Configuration
For fine-grained control over process execution — custom timeouts, cancellation strategies, buffered vs. non-buffered output, and builder-based configuration — see the Configuration Guide and the Choosing your Invocation Pattern guide in the documentation portal.
Middleware
CliInvoke's ProcessInvoker supports an optional middleware system that lets you plug cross-cutting concerns — logging, validation, platform selection, retries — around the process pipeline without changing how you call it. Middleware wraps the terminal pipeline in the order you register, and call sites (ExecuteAsync, ExecuteBufferedAsync) remain identical.
Built-in middleware includes UseLogging, UsePostExitValidation, UsePowerShell, and UseCmd. Middleware can be configured by hand or through DI via the IProcessMiddlewareBuilder callback in AddCliInvoke.
For the full guide — constructor details, the IProcessMiddleware contract, DI configuration, result ownership, and the result-swap rule — see the Middleware Guide.
Resource Disposal
CliInvoke has exactly three Resource-Owning Types that implement IDisposable and must be disposed after use to avoid resource leaks (open pipe handles, kernel handles, and pinned SecureString buffers):
| # | Type | What it owns |
|---|---|---|
| 1 | IExternalProcess |
Underlying System.Diagnostics.Process (pipes, handles, threads) |
| 2 | UserCredential |
SecureString password buffer |
| 3 | UserCredentialSpec |
SecureString password buffer staged for Build() |
No other CliInvoke type implements IDisposable. Always wrap these types in using or await using statements.
ProcessConfiguration is a plain immutable value object and does not implement IDisposable. The StandardInput (StreamWriter) and UserCredential you place inside it remain your responsibility to dispose — CliInvoke never disposes them on your behalf.
For the full disposal reference — ownership rules, disposal patterns, and a checklist — see the Resource Disposal Guide.
Middleware does not change these rules. A middleware chain returns the process result un-disposed to the caller, so the disposal contract described above applies exactly as it does without middleware. See Middleware for the result-ownership note.
Documentation
Full documentation is available in the CliInvoke Developer Portal. Pick the path that fits you:
| Who you are | Start here |
|---|---|
| Beginner — "I just need to run a command" | Quickstart → Choosing your Invocation Pattern |
| Professional Developer — "I'm building a testable app with DI" | Getting Started → Configuration |
| Power User — "I need full lifecycle control" | Choosing your Invocation Pattern → IExternalProcess → Architecture |
Upgrading to 3.0.0? The CliRun.UseExternalProcessFactory / CliRun.UseFilePathResolver
methods, the configurable ExitConfiguration setter, and several ProcessInvoker /
ExternalProcess constructors were removed. CliRun is now a stateless
batteries-included facade; callers needing a custom factory or resolver should use
IProcessInvoker (or the DI container) instead. See the
3.0.0 Migration Guide and
CHANGELOG.md for the full breaking-change list.
Other guides: Troubleshooting · Migration Guides · Building from Source
How to Build CliInvoke's code
Please see building-cliinvoke.md for how to build CliInvoke from source.
How to Contribute to CliInvoke
Please see the CONTRIBUTING.md file for code and localisation contributions.
If you want to file a bug report or suggest a potential feature to add, please check out the GitHub issues page to see if a similar or identical issue is already open. If there isn't already a relevant issue filed, please file one here and follow the respective guidance from the appropriate issue template.
License
CliInvoke is licensed under the MPL 2.0 license. You can learn more about it here
Should your project incorporate CliInvoke, ensure that the full text of CliInvoke's LICENSE.txt is either incorporated into your third-party licenses TXT file or provided as a distinct TXT file within your project's repository.
CliInvoke Assets
The CliInvoke icon is a separately-owned asset and is not licensed under MPL-2.0 like the rest of the codebase.
If you fork CliInvoke and re-distribute it, please replace the icon with your own artwork
unless you have written permission from the maintainer. To request permission, open a
GitHub issue tagged asset-license.
Star History
<a href="https://www.star-history.com/?repos=alastairlundy%2Fcliinvoke&type=date&logscale=&legend=top-left"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=alastairlundy/cliinvoke&type=date&theme=dark&legend=top-left" /> <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=alastairlundy/cliinvoke&type=date&legend=top-left" /> <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=alastairlundy/cliinvoke&type=date&legend=top-left" /> </picture> </a>
Acknowledgements
Projects
This project would like to thank the following projects for their work:
For more information, please see the THIRD_PARTY_NOTICES file.
| 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
- CliInvoke.Core (>= 3.0.0-beta.1)
- Microsoft.Extensions.Caching.Memory (>= 10.0.11)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on CliInvoke:
| Package | Downloads |
|---|---|
|
CliInvoke.Extensions
Adds a ``AddCliInvoke`` Dependency Injection extension method to enable easy CliInvoke setup when using the Microsoft.Extensions.DependencyInjection package. |
|
|
CliInvoke.Specializations
CliInvoke Specializations is a library for providing pre-configured Specializations of CliInvoke's ProcessConfiguration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-beta.2 | 53 | 8/31/2026 |
| 3.0.0-beta.1 | 137 | 8/30/2026 |
| 3.0.0-alpha.10 | 65 | 8/25/2026 |
| 3.0.0-alpha.9 | 181 | 8/19/2026 |
| 3.0.0-alpha.8 | 68 | 8/13/2026 |
| 3.0.0-alpha.7 | 213 | 7/28/2026 |
| 3.0.0-alpha.6 | 69 | 7/19/2026 |
| 2.11.0 | 101 | 9/2/2026 |
| 2.10.5 | 125 | 8/30/2026 |
| 2.10.4 | 124 | 8/26/2026 |
| 2.10.3 | 151 | 8/19/2026 |
| 2.10.2 | 157 | 8/15/2026 |
| 2.10.1 | 169 | 8/5/2026 |
| 2.9.4 | 104 | 8/30/2026 |
| 2.9.3 | 111 | 8/30/2026 |
| 2.9.2 | 126 | 8/19/2026 |
| 2.9.1 | 132 | 8/15/2026 |
| 2.9.0 | 160 | 7/19/2026 |
| 2.8.5 | 112 | 8/30/2026 |
| 2.8.4 | 110 | 8/30/2026 |
### Added
- Output truncation middleware with configurable size limits and custom handlers
- `CachingFilePathResolver` and DI registration extensions for file-path caching
- Retry middleware (`UseRetryPolicy`) with configurable policies, linear backoff, and delay clamping
- `RetryBackoffStrategy.Linear` option; retry delay clamped to `Task.Delay` maximum
- `ValidationRule` primitive for post-exit process validation
- `GetTerminatingSignal` control-adapter heuristic
- `ProcessValidationException` type
### Changed
- `CliInvoke.Extensions` folded into the main package
- `IDisposable` dropped from `ProcessConfiguration`
- `PathEnvironmentVariable` moved to `CliInvoke`
- Extension types relocated into `src/CliInvoke/Extensions` tree
- `ArgumentsSpec` internals reworked
- Per-call allocations eliminated in result parsing and argument building
- LINQ usage removed from `ProcessConfiguration` to cut allocations
- `ProcessResult.Equals` now uses exact runtime-type matching for symmetric equality
- Process launch and logging paths made more robust
- `AddEnumerable` now fails fast on null entries
- `BufferedProcessResult.WasTruncated` made immutable and included in equality
- `UseRetryPolicy` DI registration fixed to decorate the active (last) `IFilePathResolver` registration
- Default `IProcessResultValidator.ShouldRetry` inverted to `!Validate(result)`
- Caching resolver now decorates the active (last) `IFilePathResolver` registration
### Fixed
- `Canceled` no longer reports `false` after graceful timeout cancellation
- Deadlock resolved: buffered/piped capture now starts without awaiting process exit
- `LocateFileFromDirectory` rechecks resolved `FileInfo` existence before returning
- POSIX argument escaping fixed: `EscapeInner` double-backslashes before quotes and emits POSIX backslashes literally for correct round-tripping
- Stale escaping expectations in `ProcessConfigurationBuilderTests` corrected
- Argument-escaping assertions now platform-aware
- `ProcessValidationException` constructors fixed
- `UserCredential` constructor and validation rules fixed