C#命令行参数解析库System.CommandLine介绍
命令行参数
平常在日常的开发过程中,会经常用到命令行工具。如cmd下的各种命令。
以下为sc命令执行后的截图,可以看到,由于没有输入任何附带参数,所以程序并未执行任何操作,只是输出了描述和用法。

系统在创建一个新进程时,会传一个命令行给它,也就是命令行字符串。
程序需要对命令行字符串进行解析,并执行相应操作。
如使用sc query可以查询当前系统的服务:

在C#中的控制台程序中,Main函数中传入的args字符串数组,就是系统传入进程的命令行参数。

在构建具有复杂命令行参数的控制台程序时 ,手动解析参数就变得非常麻烦。这里推荐一个开源的库,可以更加方便的解析命令行参数。
System.CommandLine介绍
System.CommandLine是一个基于.Net Standard 2.0(支持.Net FrameWork 4.6.1.2+和.Net Core 2.0+)的命令行参数解析库,项目地址 https://github.com/dotnet/command-line-api,目前,该项目还是属于beta状态,期待以后的正式版本。
由于不是正式版本,在Nuget中引用时,需要钩上Include prerelease,才能找到这个包。

System.CommandLine的一些基本概念
Token(标记)
命令行的每个单词都是一个标记,如下面的"sc"、"query"和"eventlog"都是一个Token

Commands(命令)
Commands就是应用程序根据Token执行相应的操作(在System.CommandLine库中,对应 Command类)
Root Command(根命令)
根命令是代表可执行程序本身的Commands,如 sc(在System.CommandLine库中,对应RootCommand类)
SubCommands(子命令)
一些命令行程序会有SubCommands,如上面的sc query中的query就是子命令(在System.CommandLine,对应Command类)
Options(可选项)
Options就是传递给Commands的命名参数,如 app -myoption123中的 -myoption 123就是一个Options
Argument(参数)
参数就是传递给选项或命令的值。
说明:
常规的调用如下:
xx.exe [options] <argument> [command]
Delimiters(分隔符)
分隔符就是把Options的命令和值分开的符号
如下三种写法都是一样的,可以使用空格、=或 :符号
app -myoption 123
app -myoption=123
app -myoption:123
Aliases(别名)
可以为命令或选项设置较短的别名,如
-v, --verbose
--o, --option
System.CommandLine使用
在下面的示例中,我们会构建一个简单的控制台爬虫工具。
1、使用Visual Studio 2019创建一个.Net Core控制台程序crawler-line

2、导入System.CommandLine包
3、创建一个RootCommand

1 var rootCommand = new RootCommand
2 {
3 new Argument<string>(
4 "url","web site url"),
5 new Option<bool>(new string[]{ "--gethtml" ,"-html"},"Get html source"),
6 new Option<bool>(new string[]{ "--getimage" ,"-image"},"Get images"),
7 new Option<bool>(new string[]{ "--regex-option" ,"-regex"},"Use regex"),
8 new Option<bool>(new string[]{ "--htmlagilitypack-option", "-agpack"},"Use HtmlAgilityPack"),
9 new Option<bool>(new string[]{ "--anglesharp-option", "-agsharp"},"Use AngleSharp"),
10 new Option<string>(new string[]{ "--download-path" ,"-path"},"Designate download path"),13 };

说明:
可通过Option类的构造函数重载,为Option指定默认值。
1 public Option(string alias, Func<T> getDefaultValue, string? description = null);
如上面的-path Option,指定默认值为D:\download,如下:
1 new Option<string>(new string[]{ "--download-path" ,"-path"},getDefaultValue:()=>"D:\\download","Designate download path"),
也可以先实例化RootCommand对象,再通过Add的方式添加Argument和Option,如下:
1 var rootCommand = new RootCommand();
2 //添加 Argument
3 rootCommand.AddArgument(new Argument<string>("url","web site url"));
4 //添加 Option
5 rootCommand.AddOption(new Option<string>(new string[] {"--download-path","-path" },"download path"));
4、添加当前命令行程序的描述信息

1 rootCommand.Description = ".Net Core command-line crawler.";
5、解析Argument和Option
rootCommand.Handler = CommandHandler.Create<string, bool, bool, bool, bool, bool, string>((string url, bool html, bool image, bool regex, bool agpack, bool agsharp, string path) => {
});
如果觉得参数太长,可以封装成类,再进行调用,如下:

1 public class CrawlerOption
2 {
3 public string Url { get; set; }
4 public bool GetHtml { get; set; }
5 public bool GetImage { get; set; }
6 public bool RegexOption { get; set; }
7 public bool HtmlagilitypackOption { get; set; }
8 public bool AnglesharpOption { get; set; }
9 public string DownloadPath { get; set; }
10 }


1 rootCommand.Handler = CommandHandler.Create<CrawlerOption>((crawlerOption) =>
2 {
3
4 })

6、添加Command并为Command添加处理函数

1 //添加 Command
2 var githubCommand = new Command("github", "fork me on github");
3 //添加 Command的处理函数
4 githubCommand.Handler = CommandHandler.Create(() => { System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo("cmd", $"/c start https://github.com/zhaotianff/Crawler-Line")); });5 //将Command添加 到RootCommand
6 rootCommand.AddCommand(githubCommand);

说明:
1、RootCommand是顶级命令,RootCommand可以添加Command,Command又可以再添加SubCommand。如此可以无限循环,没有限制 。但建议还是不要添加太多级的Command,调用的时候会不太友好
2、Command和RootCommand原理一样,如果需要为Command添加Argument、Option和Command,可以参照前面的示例
7、调用解析
1 return rootCommand.InvokeAsync(args).Result;
8、调用示例

#执行github command
crawler-line.exe github
#执行github subcommand
crawler-line.exe github sub
#执行argument option
crawler-line.exe http://www.baidu.com -path "D:\test"

特别提示:
前面示例中,都是为RootCommand添加的Argument和Option,如果又指定 -path(Option),又执行github(Command)肯定会失败。因为github这个命令是RootCommand的子命令,而-path选项是为RootCommand添加的
示例代码
https://github.com/zhaotianff/Crawler-Line/tree/v1.0
C#命令行参数解析库System.CommandLine介绍的更多相关文章
- Google开源命令行参数解析库gflags
Google开源命令行参数解析库gflags http://blog.csdn.net/lming_08/article/details/25072899 CMDLINE的解析 http://blog ...
- python命令行参数解析模块argparse和docopt
http://blog.csdn.net/pipisorry/article/details/53046471 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的o ...
- golang-flag - 命令行参数解析
flag - 命令行参数解析 在写命令行程序(工具.server)时,对命令参数进行解析是常见的需求.各种语言一般都会提供解析命令行参数的方法或库,以方便程序员使用.如果命令行参数纯粹自己写代码解析, ...
- gflags命令行参数解析
gflags库是google开源的命令行参数解析工具. 安装 官方没有提供二进制库,但是Debian/Ubuntu平台本身提供了二进制库,可以直接git clone https://github.co ...
- PHP 命令行参数解析工具类
<?php/** * 命令行参数解析工具类 * @author guolinchao * @email luoyecb@163.com */class CommandLine{ // store ...
- [Go] 命令行参数解析包(flag 包)使用详解
Go 的 flag 包可以解析命令行的参数. 一.命令行语法 命令行语法主要有以下几种形式: cmd -flag // 只支持bool类型 cmd -flag=xxx cmd -flag ...
- $命令行参数解析模块argparse的用法
argparse是python内置的命令行参数解析模块,可以用来为程序配置功能丰富的命令行参数,方便使用,本文总结一下其基本用法. 测试脚本 把以下脚本存在argtest.py文件中: # codin ...
- Python命令行参数解析模块getopt使用实例
Python命令行参数解析模块getopt使用实例 这篇文章主要介绍了Python命令行参数解析模块getopt使用实例,本文讲解了使用语法格式.短选项参数实例.长选项参数实例等内容,需要的朋友可以参 ...
- python命令行参数解析OptionParser类用法实例
python命令行参数解析OptionParser类用法实例 本文实例讲述了python命令行参数解析OptionParser类的用法,分享给大家供大家参考. 具体代码如下: from opt ...
- Python 中命令行参数解析工具 docopt 安装和应用
什么是 docopt? 1.docopt 是一种 Python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 2.使用这种语言可以在自己的脚本中,添加一些规则限制. ...
随机推荐
- 2024-04-13:用go语言,给定一个整数数组 `nums`, 请编写一个函数,返回一个新的数组 `counts`。 满足以下条件:对于每个 `nums[i]`, `counts[i]` 表示在
2024-04-13:用go语言,给定一个整数数组 nums, 请编写一个函数,返回一个新的数组 counts. 满足以下条件:对于每个 nums[i], counts[i] 表示在 nums[i] ...
- linux 忘记密码怎么破?
前言 适合硬件在自己旁边的,不适合云服务器,云服务器很方便的,可以直接重置密码,因为云服务器都是虚拟机. 正文 1.步骤 进入到可以看到节目的视图,按下esc键进入下面的视图! 2.接着进入下面的界面 ...
- leetcode第 181 场周赛
5364. 按既定顺序创建目标数组 给你两个整数数组 nums 和 index.你需要按照以下规则创建目标数组: 目标数组 target 最初为空. 按从左到右的顺序依次读取 nums[i] 和 in ...
- 剑指offer39(Java)-数组中出现次数超过一半的数字(简单)
题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, ...
- 全链路灰度新功能:MSE 上线配置标签推送
简介: 本文介绍了全链路灰度场景给配置管理带来的问题,介绍了 MSE 针对这一场景的解决方案,并通过实践的方式展示了配置标签推送的使用流程.后续,MSE 还会针对配置治理做更多的探索,帮助用户更好地解 ...
- 持续定义Saas模式云数据仓库+实时搜索
简介: 本文由阿里云计算平台事业部 MaxCompute 产品经理孟硕为大家带来<持续定义Saas模式云数据仓库+实时搜索>的相关分享.以下是视频内容精华整理,主要包括以下三个部分:1.W ...
- iOS 端容器之 WKWebView 那些事
简介: 本文主要是关于在端容器设计开发过程中,WKWebView 使用上遇到的一些问题和解决办法 作者 | 驽良 来源 | 阿里技术公众号 一 背景 熟悉 iOS\macOS Hybrid 混合 ...
- [FAQ] web3js, Error: [number-to-bn] while converting number 0.1 to BN.js instance, error: invalid number value
我们在调用合约方法时,都可以传一些参数的,比如转账金额 value. value 的单位是 wei,这是一个很小的单位,所以一般数值很大. 如果误把 ether 当成 wei 传参,就会报标题中的错误 ...
- 从右边开始寻找整数的第k位
从右边开始寻找整数的第k位 Implement match_k, which takes in an integer k and returns a function that takes in a ...
- WPF 字体 FontStyle 的 Italic 和 Oblique 的区别
本文介绍在 WPF 里面的字体属性 FontStyle 的 Italic 和 Oblique 的斜体差别 本文的图片和知识来自: #265 – Specifying Values for FontSt ...