zoukankan      html  css  js  c++  java
  • dotnet 使用 System.CommandLine 写命令行程序

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

    我写过一篇关于命令行解析的博客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.

    我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

    如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

  • 相关阅读:
    Hive的mysql安装配置
    Linux下的MySQL安装
    Hive的安装与基础指令
    浅谈数据库和数据仓库
    Hive的学习之路(理论篇)
    Spring---bean的命名
    Spring---单例模式(Singleton)的6种实现
    Spring---加载配置文件的几种方法(org.springframework.beans.factory.BeanDefinitionStoreException)
    Spring---配置文件概述
    Spring---Bean生命周期
  • 原文地址:https://www.cnblogs.com/lindexi/p/12086837.html
Copyright © 2011-2022 走看看