Introduction to CliWrap
CliWrap is an intuitive library designed to interact with external command-line interfaces seamlessly. It enables users to launch processes, handle input and output streams, and manage cancellation in a fluent, asynchronous manner.
Terms of Use
Using CliWrap implies agreeing to support Ukraine's territorial integrity and condemning the Russian military aggression. More details about the situation and how to help can be found on their website.
Installation
You can easily add CliWrap to your project using NuGet with the following command:
dotnet add package CliWrap
Key Features
CliWrap offers numerous features that distinguish it as a robust tool for CLI interactions:
- Process Abstraction: Provides a structured way to use
System.Diagnostics.Process
. - Fluent Configuration: Simplifies configuration of commands via fluent API.
- Flexible Piping: Supports complex piping scenarios for data input and output.
- Asynchronous API: Enables non-blocking operations with built-in cancellation support.
- Platform Compatibility: Works on Windows, Linux, and macOS, targeting .NET Standard 2.0+, .NET Core 3.0+, and .NET Framework 4.6.2+.
- Immutability and Safety: Designed with immutability in mind and guards against common deadlock scenarios.
- No External Dependencies: Requires no additional libraries to function.
Usage Overview
CliWrap revolves around the concept of a command. This encapsulates all instructions needed to run a process. Here’s a brief overview of using CliWrap to run a command:
using CliWrap;
var result = await Cli.Wrap("path/to/exe")
.WithArguments(["--foo", "bar"])
.WithWorkingDirectory("work/dir/path")
.ExecuteAsync();
This asynchronously starts the specified executable with given arguments and directory, and provides information about the execution result.
Handling Output and Errors
Typically, CliWrap directs a process's standard input, output, and error streams to null, unless specified otherwise. Stream configurations can be modified using:
using CliWrap;
var stdOutBuffer = new StringBuilder();
var stdErrBuffer = new StringBuilder();
var result = await Cli.Wrap("path/to/exe")
.WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOutBuffer))
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer))
.ExecuteAsync();
The above setup collects output in StringBuilder
instances for further processing post-execution.
Command Configuration
CliWrap's fluent API supports various configurations such as setting arguments, working directories, environment variables, and more. Here is how you can set different aspects of a command:
- Arguments: You can choose to set arguments using arrays, builders or directly from strings for simplicity and reusability.
- Environment Variables: Add or modify environment variables for the child process.
- Working Directory and Credentials: Specify a working directory and credentials to execute the process under a specific user.
Advanced Piping
CliWrap's flexible piping allows you to redirect streams and chain commands with minimal overhead:
await (File.OpenRead("input.txt") | Cli.Wrap("foo") | File.Create("output.txt")).ExecuteAsync();
Utilize PipeSource
and PipeTarget
with versatile factory methods to adapt stdin
, stdout
, and stderr
for your needs.
Execution Models
CliWrap includes different models for command execution:
- Buffered Execution: Collects outputs as text, which can be easier for certain scenarios.
- Event-stream Execution: A more interactive approach, processing output and error streams in real-time.
In summary, CliWrap enhances C# developers’ ability to manage command-line processes with ease and power, while remaining highly efficient and secure across multiple platforms.