title author date CreateTime categories
dotnet 使用 System.CommandLine 写命令行程序
lindexi
2019-08-31 16:55:58 +0800
2019-04-20 17:22:15 +0800
dotnet

在写命令行程序的时候,会遇到命令行解析的问题,以及参数的使用和规范化等坑。现在社区开源了命令行项目,可以帮助小伙伴快速开发命令行程序,支持自动的命令行解析和规范的参数

我写过一篇关于命令行解析的博客C#命令行解析工具 但是这个方法不是很好用

在社区找到了 System.CommandLine 这是一个还在开发过程的很好用的一个库,里面用了很多很黑的写法

我创建了一个项目,我删除了原来的 Main 函数,使用下面的代码替换原来的 Main 函数,然后居然是可以编译通过运行的

        static void Main(string name, string text)
{
Console.WriteLine($"{name}{text}");
}

当然在开始之前我需要安装两个 Nuget 库

  • System.CommandLine.DragonFruit
  • System.CommandLine.Rendering

可以通过创建一个 dotnet core 项目,编辑项目文件,添加下面代码

  <ItemGroup>
<PackageReference Include="System.CommandLine.DragonFruit" Version="0.2.0-alpha.19174.3" />
<PackageReference Include="System.CommandLine.Rendering" Version="0.2.0-alpha.19174.3" />
</ItemGroup>

现在尝试使用 dotnet 命令行运行,请使用下面代码

dotnet run -- --name 林德熙 --text 是逗比

在 dotnet 命令使用 -- 分割调用的参数,也就是在 -- 后面的参数将会传递到程序里面

于是就相当于运行了测试项目,传入参数 --name 林德熙 --text 是逗比 可以看到输出

林德熙是逗比

这个例子的项目请看测试程序

当然命令行的参数写法有很多,上面的程序也支持下面的参数

dotnet run -- --name:林德熙 --text:是逗比

当然一个命令行程序,如果就一个 exe 发给小伙伴,那么小伙伴怎么知道如何使用?在软件工程里面,在这一行默认的就是输入 --help 就输出帮助信息

于是我在主函数添加一点注释

        /// <summary>
/// 欢迎访问我的博客 http://blog.lindexi.com 从入门到精通
/// </summary>
/// <param name="name">逗比名</param>
/// <param name="text">逗比</param>
static void Main(string name, string text)

此时输入 dotnet run -- --help 就可以看到下面代码

DallairhacelKurbegofa:
欢迎访问我的博客 http://blog.lindexi.com 从入门到精通 Usage:
DallairhacelKurbegofa [options] Options:
--name <NAME> 逗比名
--text <TEXT> 逗比
--version Display version information

那么这个库是如何做黑科技让你的主函数可以修改参数的?

打开System.CommandLine.DragonFruit.targets 就可以看到 GenerateRealEntryPointType 修改启动项目

修改 StartupObject 可以指定调用的主函数是哪个类里的

    <PropertyGroup>
<StartupObject>AutoGeneratedProgram</StartupObject>
</PropertyGroup>

创建动态代码写入到 obj 文件夹里面的 xx.g.cs 文件,写入下面代码

// <auto-generated>This file was created automatically</auto-generated>
using System.CommandLine.DragonFruit;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; [CompilerGenerated]
internal class AutoGeneratedProgram
{
public static async Task<int> Main(string[] args)
{
return await CommandLine.ExecuteAssemblyAsync(
entryAssembly: typeof(global::AutoGeneratedProgram).Assembly,
args: args);
}
}

因为运行的启动函数就是 AutoGeneratedProgram 里面的主函数,所以其实你写的主函数不是主函数

如果想自己也修改主函数,请看Roslyn 通过 NuGet 库修改应用程序入口函数

想知道这个库是如何做的,请看源代码dotnet/command-line-api: System.CommandLine: Command line parsing, invocation, and rendering of terminal output.

2019-8-31-dotnet-使用-System.CommandLine-写命令行程序的更多相关文章

  1. dotnet 使用 System.CommandLine 写命令行程序

    在写命令行程序的时候,会遇到命令行解析的问题,以及参数的使用和规范化等坑.现在社区开源了命令行项目,可以帮助小伙伴快速开发命令行程序,支持自动的命令行解析和规范的参数 我写过一篇关于命令行解析的博客C ...

  2. C# 借助CommandLine 写命令行工具 在数据库中创建job

    首先需要用到  CommandLine.dll 提供两个下载链接,云盘是我自己上传的,也就是我在用的 http://commandline.codeplex.com/ https://pan.baid ...

  3. 2019-11-29-dotnet-使用-System.CommandLine-写命令行程序

    title author date CreateTime categories dotnet 使用 System.CommandLine 写命令行程序 lindexi 2019-11-29 08:33 ...

  4. 手写笔记变PDF-几行代码变命令行程序为图形化界面

    前言 最近发现了一个非常不错的Python类库----Gooey, https://github.com/chriskiehl/Gooey 在它的帮助下我们可以非常方便的将一个命令行程序升级成一个图形 ...

  5. UNIX环境编程学习笔记(22)——进程管理之system 函数执行命令行字符串

    lienhua342014-10-15 ISO C 定义了 system 函数,用于在程序中执行一个命令字符串.其声明如下, #include <stdlib.h> int system( ...

  6. 【转载】在LoadRunner中执行命令行程序之:popen()取代system()

    我想大家应该都知道在LoadRunner可以使用函数system()来调用系统指令,结果同在批处理里执行一样. 但是system()有个缺陷:无法获取命令的返回结果. 也许你可以用`echo comm ...

  7. 在LoadRunner中执行命令行程序之:popen()取代system()

    我想大家应该都知道在LoadRunner可以使用函数system()来调用系统指令,结果同在批处理里执行一样. 但是system()有个缺陷:无法获取命令的返回结果. 也许你可以用`echo comm ...

  8. 用什么库写 Python 命令行程序?看这一篇就够了

    作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...

  9. 通过System.CommandLine快速生成支持命令行的应用

    一直以来,当我们想让我们的控制台程序支持命令行启动时,往往需要编写大量代码来实现这一看起来很简单的功能.虽然有一些库可以简化一些操作,但整个过程仍然是一个相当枯燥而乏味的过程.我之前也写过一些文章简单 ...

随机推荐

  1. sql 书写顺序

    SELECT select_list [ INTO new_table ] FROM table_source [ WHERE search_condition ] [ GROUP BY group_ ...

  2. chage 修改用户密码有效期限的命令

    chage 用语法格式: chage [-l] [-m 最小天数] [-M 最大天数] [-W 警告] [-I 失效日] [-E 过期日] [-d 最后日] 用户 前面已经说的好多了,这个只是一笔带过 ...

  3. 线性求所有数模p的乘法逆元

    推理: 假如当前计算的是x在%p意义下的逆元,设$p=kx+y$,则 $\Large kx+y\equiv 0(mod\ p)$ 两边同时乘上$x^{-1}y^{-1}$(这里代表逆元) 则方程变为$ ...

  4. Leetcode238. Product of Array Except Self除自身以外数组的乘积

    给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: [1 ...

  5. Leetcode520Detect Capital检测大写字母

    给定一个单词,你需要判断单词的大写使用是否正确. 我们定义,在以下情况时,单词的大写用法是正确的: 全部字母都是大写,比如"USA". 单词中所有字母都不是大写,比如"l ...

  6. [Array] 561. Array Partition I

    Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1 ...

  7. JQuery--extend的使用

    $.extend({a,b,c},{a,bd}); 里面的对象属性如果 存在就替换,如果不存在就添加 var loadData = function (order) { var obj = getPa ...

  8. 20190828 [ Night ] - 弋

    半集训可还行…… 半集训第一次模拟 考试过程 好像是上回的同套题. ××内个$\text{english}$真毒瘤 T1 什么玩意? $chinese$? 前面两句背景是个? 需要$\Theta(1) ...

  9. 【solr】Solr5.5.4+Zookeeper3.4.6+Tomcat8搭建SolrCloud集群

    Solr5.5.4+Zookeeper3.4.6+Tomcat8搭建SolrCloud集群 SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力 ...

  10. Linux 基础命令4进程

    ID和PID的产生 ps( process status) 查看现在的进程 上例中,列出了两个进程,进程 5198 和进程 10129,各自代表命令 bash 和 ps.正如我们所看到的, 默认情况下 ...