System.CommandLine 创建 C# 命令行工具需定义命令、选项、参数并绑定处理逻辑;安装 v2.0.0-beta4 或更高版;用 RootCommand 和 Option/Argument 构建结构;SetHandler 参数顺序须与注册顺序一致;支持子命令、自动帮助及错误提示。

用 System.CommandLine 创建 C# 命令行工具,核心是定义命令、选项、参数,再绑定处理逻辑——它比手动解析 args 更清晰,也比传统 Console.ReadLine() 交互更专业。
安装 System.CommandLine
在项目中通过 NuGet 安装最新稳定版(推荐 v2.0.0-beta4 或更高):
- CLI 方式:
dotnet add package System.CommandLine --version 2.0.0-beta4 - 或在 .csproj 中添加:
注意:v2 是当前主推版本,API 更统一,文档和示例也以 v2 为主;避免混用 v1(已归档)。
定义基础命令和选项
从 RootCommand 开始,用 Option 添加开关,用 Argument 接收位置参数:
var root = new RootCommand("我的工具:处理文本文件");
var inputOpt = new Option<string>("--input", "输入文件路径") { IsRequired = true };
var verboseOpt = new Option<bool>("--verbose", "显示详细日志");
<p>root.AddOption(inputOpt);
root.AddOption(verboseOpt);</p>
<p>root.SetHandler((input, verbose) =>
{
Console.WriteLine($"处理文件:{input}");
if (verbose) Console.WriteLine("详细模式已启用");
}, inputOpt, verboseOpt);
</p></bool></string>
关键点:
- SetHandler 绑定执行逻辑,参数顺序必须与 AddOption / AddArgument 传入顺序一致
- 选项名支持短格式(如 -i)和长格式(--input),可同时注册:new Option
支持子命令(如 git commit / push)
用 Command 创建子命令,再挂到根命令下:
var commitCmd = new Command("commit", "提交更改");
var messageOpt = new Option<string>("--message", "提交信息");
commitCmd.AddOption(messageOpt);
commitCmd.SetHandler(msg => Console.WriteLine($"提交:{msg}"), messageOpt);
<p>root.AddCommand(commitCmd);</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill10243" title="openclaw-github-config-impact"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20cf0281539.jpg" alt="openclaw-github-config-impact" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill10243" title="openclaw-github-config-impact" class="overflowclass">openclaw-github-config-impact</a>
<p class="overflowclass">OpenClaw 技能 — 给定一个 GitHub 仓库 URL,自动解析出 owner/repo 名称,发现其中的 YAML/properties 配置文件及其配对的中文字段说明;在 `workspace/{repo}/` 目录下按同步日期(格式为 `YYYY-MM-DD`)创建时间戳子目录;写入 `.openclaw-config-state.json` 状态文件。每次用户提问前,先比对远程仓库当前 ref(如 `main` 或 `master`)的最新提交 SHA 与本地状态文件中记录的 SHA:</p>
</div>
<a rel="nofollow" href="/xiazai/skill10243" title="openclaw-github-config-impact" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>// 运行:dotnet run -- commit --message "feat: add login"
</p></string>
子命令可嵌套多层,适合功能复杂的 CLI 工具(比如 dotnet tool restore 中的 tool 是命令,restore 是其子命令)。
自动帮助与错误提示
无需手写 --help 逻辑,System.CommandLine 默认支持:
- 运行
dotnet run -- --help→ 显示根命令帮助 - 运行
dotnet run -- commit --help→ 显示commit子命令帮助 - 参数缺失、类型错误时自动报错并提示正确用法
还可自定义帮助文本:root.Description = "一个轻量级文件处理器",或为选项加说明:inputOpt.Description = "必填:UTF-8 编码的 .txt 文件"。
基本上就这些。不复杂但容易忽略的是 handler 参数顺序和 option 注册顺序必须严格对应——写错会导致运行时报 ArgumentException。其他高级用法(如自定义类型转换、中间件管道、国际化)可按需查官方文档。










