System.CommandLine parsed values don't match input

Viewed 1126

I am trying to use System.CommandLine and I haven't been able to get my handler to see any of the values that I'm passing in. I've tried the simplest command line program just to see if any values make it through and so far I haven't been successful. I am targeting .NET 4.7.2 and I'm using 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);
        }
    }

No matter how I call my application, I am not seeing the value of willContinue come across as true.

myapp.exe --continue -> False

myapp.exe --cont -> Unrecognized command or argument '--cont' (my options are at least getting recognized)

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

myapp.exe --help ->

myapp:
Testing System.CommandLine

Usage:
myapp [options]

Options:
--continue continue option
--version Show version information
-?, -h, --help Show help and usage information

2 Answers

You need to fix 2 things:

  1. add the option type, which is bool
  2. change the name of the option to match the parameter name

the following command works:

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

and call it like so

myapp.exe --willContinue true

the option name and parameter name don't always have to match-up, but in this case it doesn't work because 'continue' is a reserved word

I wanted to add an answer to be very clear about exactly what resolved my problem

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);
    }
}

Because the Argument/Option/Command/anything else that can be added to a Command object has to match the name of the parameter used when creating the CommandHandler, the names used can't have spaces, begin with numbers, or use a C# keyword (not having spaces is not a problem for most items because it would be silly/impossible to have an option --will continue, but with arguments you don't have to put the name of the argument into your command line call because it is listed in the usage as <argument name> and the argument is read in by position, so I was wanting to use an argument name like <file directory>, but that doesn't work because you can't have a variable name with spaces in it)

Related