1. 背景
在.NET开发中,我们经常需要创建命令行应用程序。比如一些工具类应用程序,或者一些自动化脚本等。为了方便用户使用这些应用程序,我们通常会提供一个命令行界面,用户可以通过命令行参数来指定应用程序的行为。
然而,处理命令行参数并不是一件容易的事情。通常情况下,我们需要编写大量的代码来解析命令行参数,并且处理各种不同的情况。这不仅会增加我们的工作量,还会增加应用程序的复杂性。
为了简化这个过程,我们可以使用CommandLine库。这是一个.NET库,专门用于创建命令行应用程序。它提供了一种简单的方法来解析命令行参数,并且可以帮助我们构建一个功能强大的命令行界面。
在之前的文章中,我们在介绍SangServerTool工具时就已经介绍了 CommandLineParser 这个命令行解析库,虽然其使用上非常友好,但是因为这个库积压了很多issue,并且已经很久没有维护了,同时对裁剪的支持也不够好。所以,我们这里介绍一个新的库 CommandLine。
2. CommandLine 介绍
System.CommandLine
是一个由官方维护的为 .NET 应用程序设计的库,专注于简化命令行界面的创建和管理。它旨在帮助开发者构建那些需要解析命令行参数、选项和命令的应用程序,同时提供丰富的功能来支持帮助文本的生成、参数绑定、依赖注入等。
核心功能
- 命令行参数解析:自动解析用户从命令行输入的参数、选项和命令,减少手动解析的需要。
- 生成帮助文本:自动生成帮助文本,为用户提供关于如何使用命令行应用的指导。
- 参数绑定:将命令行输入绑定到应用程序的数据模型或处理逻辑,简化参数处理。
- 支持自动补全:支持 Tab 键自动补全功能,提高用户使用命令行应用的效率。
- 响应文件支持:允许用户通过文件输入命令行参数,适用于参数较多的情况。
开发者好处
- 减少样板代码:开发者可以专注于业务逻辑,而不是处理命令行解析的细节。
- 易于测试:应用逻辑可以独立于命令行输入分析代码进行测试。
- 性能优化:库设计考虑到了性能和资源使用,适合开发快速、轻量级的命令行应用。
用户好处
- 一致性:遵循 POSIX 或 Windows 约定,确保命令行输入的一致性解析。
- 易用:自动生成的帮助文本和支持的自动补全功能提高了用户体验。
3. 安装CommandLine库
System.CommandLine
库是一个 NuGet 包,可以通过 NuGet 包管理器或者 .NET CLI 来安装。在 Visual Studio 中,可以通过 NuGet 包管理器来搜索并安装 System.CommandLine
包。
dotnet add package System.CommandLine --prerelease
需要注意的是,目前 System.CommandLine
库还处于预览版阶段,所以需要添加 --prerelease
参数来安装预览版的包。
4. 命令定义的使用
这里我们以 SangServerTool
工具为例,来演示如何使用 System.CommandLine
库来定义命令行参数。SangServerTool
含有三个子命令:ddns
、ssl
和 sync
,分别对应 DDNS 动态域名解析、SSL 证书申请和远端证书同步功能。
首先,我们需要定义一个 RootCommand
对象,用于表示根命令。
using System.CommandLine;
using System.CommandLine.NamingConventionBinder;
// 创建根命令
var rootCommand = new RootCommand("SangServerTool");
然后,我们可以通过 Command
对象来定义子命令和选项。例如,我们可以定义一个 ddns
子命令,并为其添加选项。
// 定义ddns命令
var ddnsCommand = new Command("ddns", "Set DDNS.");
ddnsCommand.AddOption(new Option<string>(new[] { "--config", "-c" }, "Set config json file.") { IsRequired = true});
ddnsCommand.AddOption(new Option<int>("--delay", () => 0, "How many seconds delay?"));
ddnsCommand.AddOption(new Option<bool>("--del", () => false, "Is delete DDNS?"));
ddnsCommand.AddOption(new Option<bool>("--v6", () => false, "Is ipv6?"));
接着,我们需要定义一个处理命令的委托,并将其与命令绑定。
// 定义处理命令的委托
ddnsCommand.Handler = CommandHandler.Create<string, int, bool, bool>((config, delay, del, v6) =>
{
// 处理ddns命令
Console.WriteLine($"config: {config}");
Console.WriteLine($"delay: {delay}");
Console.WriteLine($"del: {del}");
Console.WriteLine($"v6: {v6}");
});
最后,我们将子命令添加到根命令中,并执行命令行解析。
// 将ddns命令添加到根命令
rootCommand.AddCommand(ddnsCommand);
// 解析并执行命令
return await rootCommand.InvokeAsync(args);
最后
关于 System.CommandLine
库的使用,我们在这里只是做了一个简单的介绍,更多的功能和用法可以参考官方文档。
虽然 System.CommandLine 提供了丰富的功能,但它仍然处于预览版阶段,这意味着在正式发布之前,它可能会发生重大更改。因此,开发者在使用时需要注意版本更新和兼容性问题。不过,考虑到它是由官方维护的库,未来应该会得到更好的支持和维护。