【问题标题】:System.CommandLine parsed values don't match inputSystem.CommandLine 解析的值与输入不匹配
【发布时间】:2021-02-03 21:24:02
【问题描述】:

我正在尝试使用 System.CommandLine,但我无法让我的处理程序查看我传入的任何值。我尝试了最简单的命令行程序来查看是否有任何值成功了,到目前为止我还没有成功。我的目标是 .NET 4.7.2,我正在使用 System.CommandLine 2.0.0-beta1.20574.7

    using System;
    using System.CommandLine;
    using System.CommandLine.Invocation;

    static class Program
    {
        public static void Main(string[] args)
        {
            var rootCommand = new RootCommand
            {
                new Option("--continue", "continue option")
            };

            rootCommand.Description = "Testing System.CommandLine";

            rootCommand.Handler = CommandHandler.Create<bool>
                ((willContinue) => run(willContinue));

            rootCommand.Invoke(args);
        }

        private static void run(bool willContinue)
        {
            Console.WriteLine(willContinue);
        }
    }

无论我如何称呼我的应用程序,我都没有看到 willContinue 的价值是真实的。

myapp.exe --continue -> False

myapp.exe --cont -> Unrecognized command or argument '--cont'(我的选择至少得到认可)

myapp.exe --continue true -> Unrecognized command or argument 'true'

myapp.exe --help->

我的应用程序:
测试 System.CommandLine

用法:
myapp [选项]

选项:
--continue 继续选项
--version 显示版本信息
-?, -h, --help 显示帮助和使用信息

【问题讨论】:

    标签: c# system.commandline


    【解决方案1】:

    你需要解决两件事:

    1. 添加选项类型,即bool
    2. 更改选项名称以匹配参数名称

    以下命令有效:

    var rootCommand = new RootCommand
    {
        new Option<bool>("--willContinue", "continue option")
    };
    

    这样称呼它

    myapp.exe --willContinue true
    

    选项名称和参数名称不必总是匹配,但在这种情况下它不起作用,因为“继续”是保留字

    【讨论】:

    • 看起来关键是选项名称必须与参数名称匹配。它仅适用于普通选项而不是 Option&lt;bool&gt;,它默认为 bool 标志类型选项。我将参数的名称更改为 willContinue 因为 continue 是 C# 关键字,这就是我遇到问题的地方。谢谢。
    • 看起来选项名称和参数名称确实需要匹配。我尝试使用选项名称“willContinue”和参数名称“something”,但没有找到正确的值。
    • 当定位 net5 时,我得到相反的结果:当我没有指定类型时,我得到错误 Unrecognized command or argument 'true',但我可以将方法参数名称更改为 something,它仍然有效。解释了为什么它仍处于测试阶段,我认为遵循这两个规则是一个好习惯:保持相同的名称并指定选项类型
    • 如果您使用没有类型的普通选项,则用法为myapp.exe --willContinue,并且您不指定真或假。如果该选项存在,则该值会显示为 true,如果不存在,则显示为 false,这正是我想要的。
    【解决方案2】:

    我想添加一个答案,以明确解决我的问题的确切原因

    using System;
    using System.CommandLine;
    using System.CommandLine.Invocation;
    
    static class Program
    {
        public static void Main(string[] args)
        {
            var rootCommand = new RootCommand
            {
                new Option("--willContinue", "continue option")
                //             ^This option name
            };
    
            rootCommand.Description = "Testing System.CommandLine";
    
            rootCommand.Handler = CommandHandler.Create<bool>
                ((WiLLCoNtInUe) => run(WiLLCoNtInUe));
            //     ^ HAS to match this parameter name where the command handler is created.
            //       but does not have to match case
    
            rootCommand.Invoke(args);
        }
     
        private static void run(bool canBeSomethingElse)
        // Because of how this is called ^ this does not have to match
        {
            Console.WriteLine(canBeSomethingElse);
        }
    }
    

    因为可以添加到Command 对象的参数/选项/命令/任何其他内容必须与创建CommandHandler 时使用的参数名称匹配,所以使用的名称不能有空格,以数字,或使用 C# 关键字(对于大多数项目来说,没有空格不是问题,因为有一个选项 --will continue 会很愚蠢/不可能,但使用参数时,您不必将参数的名称放入您的命令行调用,因为它在用法中列为 &lt;argument name&gt; 并且参数是按位置读取的,所以我想使用像 &lt;file directory&gt; 这样的参数名称,但这不起作用,因为你不能有带空格的变量名)

    【讨论】:

    • 可以使用c#关键字作为参数名:rootCommand.Handler = CommandHandler.Create&lt;bool&gt;((@continue)=&gt;run(@continue))(见link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多