前言
C#开发中,执行命令行操作是常见需求,但使用原生Process类往往面临代码冗长、异步支持差、错误处理繁琐等问题。
本文将介绍一款命令行交互库——CliWrap,它通过流式API设计和现代化特性,让命令行操作变得简洁、安全且强大。
为什么需要CliWrap?
传统Process类的问题
使用原生Process类时,常遇到以下问题:
-
代码冗长:需要大量样板代码处理进程启动和输出重定向
-
死锁风险:不当的流处理容易导致进程挂起
-
异步支持差:缺乏原生async/await支持
-
错误处理繁琐:退出码判断和异常处理逻辑分散
-
管道操作复杂:多进程链式调用实现困难
CliWrap的优势
-
流式API设计:链式配置,代码直观易读
-
完全异步:原生支持async/await模式
-
智能管道系统:轻松实现进程间数据传输
-
多执行模式:缓冲、事件流、管道等灵活选择
-
安全性保障:自动参数转义,防止注入攻击
安装与配置
# NuGet包管理器
Install-Package CliWrap
# .NET CLI
dotnet add package CliWrap
兼容性
-
.NET Standard 2.0+
-
.NET Core 3.0+
-
.NET Framework 4.6.2+
-
跨平台支持(Windows/Linux/macOS)
核心功能
1、基础命令执行
传统方式
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "git",
Arguments = "status",
UseShellExecute = false,
RedirectStandardOutput = true
}
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
CliWrap方式
using CliWrap;
var result = await Cli.Wrap("git")
.WithArguments(["status"])
.WithWorkingDirectory("D:/myproject/18csharp-code")
.ExecuteAsync();
Console.WriteLine($"Exit code: {result.ExitCode}");
Console.WriteLine($"Run time: {result.RunTime}");
2、输出缓冲处理
try {
var result = await Cli.Wrap("cmd")
.WithArguments(["/c", "dir", "."])
.ExecuteBufferedAsync(Encoding.UTF8);
if (result.IsSuccess) {
Console.WriteLine("Success:");
Console.WriteLine(result.StandardOutput);
} else {
Console.WriteLine($"Failed with code {result.ExitCode}");
Console.WriteLine(result.StandardError);
}
} catch (Exception ex) {
Console.WriteLine($"Exception: {ex.Message}");
}
3、实时事件流处理
await foreach (var cmdEvent in Cli.Wrap("cmd")
.WithArguments(["/c", "dir", ".", "/w"])
.ListenAsync())
{
switch (cmdEvent) {
case StartedCommandEvent started:
Console.WriteLine($"Process started, PID: {started.ProcessId}");
break;
case StandardOutputCommandEvent stdOut:
Console.WriteLine($"Output: {stdOut.Text}");
break;
case ExitedCommandEvent exited:
Console.WriteLine($"Process exited with code {exited.ExitCode}");
break;
}
}
4、管道操作
// 链式执行命令
var result = await (
Cli.Wrap("cmd").WithArguments(["/c", "echo", "Hello"]) |
Cli.Wrap("findstr").WithArguments(["Hello"]) |
PipeTarget.ToFile("output.txt")
).ExecuteAsync();
// 读取结果
if (File.Exists("output.txt")) {
var content = await File.ReadAllTextAsync("output.txt");
Console.WriteLine(content.Trim());
}
5、超时与取消控制
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
try {
var result = await Cli.Wrap("ping")
.WithArguments(["8.8.8.8", "-t"])
.ExecuteAsync(cts.Token);
} catch (OperationCanceledException) {
Console.WriteLine("Command cancelled");
}
实战模板
通用命令执行器
public class CommandExecutor {
public async Task<(bool Success, string Output, string Error)>
ExecuteAsync(string fileName, string[] args,
string workingDir = null,
TimeSpan? timeout = null)
{
var cmd = Cli.Wrap(fileName).WithArguments(args);
if (workingDir != null) cmd = cmd.WithWorkingDirectory(workingDir);
using var cts = new CancellationTokenSource(timeout ?? TimeSpan.FromMinutes(5));
try {
var result = await cmd.ExecuteBufferedAsync(cts.Token);
return (result.ExitCode == 0, result.StandardOutput, result.StandardError);
} catch (OperationCanceledException) {
return (false, "", "Timeout expired");
}
}
}
实时输出处理器
public class RealTimeProcessor {
public async Task ProcessWithCallback(string fileName, string[] args,
Action<string> onOutput = null,
Action<string> onError = null)
{
await foreach (var cmdEvent in Cli.Wrap(fileName)
.WithArguments(args)
.ListenAsync())
{
switch (cmdEvent) {
case StandardOutputCommandEvent stdOut:
onOutput?.Invoke(stdOut.Text);
break;
case StandardErrorCommandEvent stdErr:
onError?.Invoke(stdErr.Text);
break;
}
}
}
}
性能建议
1、内存管理:大量输出时使用事件流模式
2、并发控制:用SemaphoreSlim限制并发进程数
3、资源清理:及时释放CancellationTokenSource
4、错误处理:区分预期错误和系统异常
总结
CliWrap通过以下特性提升C#命令行交互体验:
-
流式API设计使代码更直观
-
原生异步支持提升响应能力
-
完善的管道系统简化复杂操作
-
生产级特性保障系统稳定性
用上 CliWrap 之后,命令行交互这块基本不用操心了。自动化脚本、CI/CD 流水线、工控软件……很多 .NET 项目现在都直接拿它当标准工具。
关键词
CliWrap、C#、命令行交互、异步编程、管道操作、进程管理、CliWrap、C#、命令行、Process、异步执行、管道操作、事件流、超时控制、.NET、系统集成
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
优秀是一种习惯,欢迎大家留言学习!
来源:mp.weixin.qq.com/s/tBf2l3oZTXg4zkr__MHpJQ