system-commandline-csharp

How to use System.CommandLine in C#

  • 5 min

System.CommandLine is a .NET library for defining and processing commands, options, and arguments in console applications.

Beyond input parsing, it allows you to generate help, validate values, and organize subcommands without manually maintaining a parser based on string[] args.

What System.CommandLine brings

System.CommandLine is a library developed by Microsoft that simplifies the creation of console applications by processing command-line arguments. Unlike traditional approaches using the string[] args array, this library allows you to define commands, subcommands, options, and arguments more explicitly with a clear syntax. Additionally, it offers advanced features such as validation, autocompletion, and the ability to automatically generate command-line help.

The System.CommandLine package is available via NuGet and is part of the .NET ecosystem, making it easily integrable into any C# console project.

Installing System.CommandLine

To start using System.CommandLine, you need to install the corresponding NuGet package. This can be done as follows:

From Visual Studio, go to the NuGet Package Manager and search for System.CommandLine. Then, click Install.

Open the terminal and run the following command in your project directory:

dotnet add package System.CommandLine
Copied!

This action adds the System.CommandLine library to your project, allowing you to start using it.

Creating a basic command

One of the main advantages of System.CommandLine is its ability to define commands in a structured way. Below is a basic example of how to define and execute a command with this library:

Basic example

using System.CommandLine;

class Program
{
    static int Main(string[] args)
    {
        Option<string> nameOption = new("--name")
        {
            Description = "Your name",
            Required = true
        };

        RootCommand rootCommand = new("Sample application");
        rootCommand.Options.Add(nameOption);
        rootCommand.SetAction(parseResult =>
        {
            string name = parseResult.GetValue(nameOption)!;
            Console.WriteLine($"Hello, {name}!");
        });

        return rootCommand.Parse(args).Invoke();
    }
}
Copied!

Code explanation

  1. Defining a RootCommand: A RootCommand is the main command that will handle command-line arguments. Here, we created a root command with a --name option, which takes a string value and is used to greet the user.

  2. Assigning an action: SetAction defines what happens when the command is executed. The action retrieves the value of --name from the parse result.

  3. Parsing and execution: Parse(args).Invoke() parses the arguments and executes the action, or displays errors and help accordingly.

Execution

If we run the program with the following arguments:

myapp.exe --name Carlos
Copied!

The output will be:

Hello, Carlos!
Copied!

This basic example shows how to create a simple command with an option that accepts an argument. System.CommandLine handles argument validation and parsing efficiently.

Working with subcommands

In more complex applications, you may need subcommands to organize operations. Subcommands allow the creation of hierarchical commands, where a main command can have several associated subcommands.

Example with subcommands

using System.CommandLine;

class Program
{
    static int Main(string[] args)
    {
        Option<string> greetName = new("--name") { Required = true };
        Command greet = new("greet", "Greet a user") { greetName };
        greet.SetAction(result =>
            Console.WriteLine($"Hello, {result.GetValue(greetName)}!"));

        Option<string> farewellName = new("--name") { Required = true };
        Command farewell = new("farewell", "Say goodbye to a user") { farewellName };
        farewell.SetAction(result =>
            Console.WriteLine($"Goodbye, {result.GetValue(farewellName)}!"));

        RootCommand rootCommand = new("Application with subcommands");
        rootCommand.Subcommands.Add(greet);
        rootCommand.Subcommands.Add(farewell);

        return rootCommand.Parse(args).Invoke();
    }
}
Copied!

Code explanation

  1. Defining subcommands: We added two subcommands to the RootCommand: greet and farewell, each with a --name option.

  2. Assigning actions: Each subcommand has an action that defines its behavior, such as greeting or saying goodbye to the user.

Execution

If we run the program with the following command:

myapp.exe greet --name Carlos
Copied!

The output will be:

Hello, Carlos!
Copied!

If we run the farewell subcommand:

myapp.exe farewell --name Carlos
Copied!

The output will be:

Goodbye, Carlos!
Copied!

This example demonstrates how to handle subcommands, which is useful for creating more structured and organized applications.

Validation and type conversion

System.CommandLine also offers advanced features like argument validation and type conversion. For example, we can validate that an argument is a number or conforms to a specific format.

Validation example

using System.CommandLine;
class Program
{
    static int Main(string[] args)
    {
        Option<int> num1Option = new("--num1") { Required = true };
        Option<int> num2Option = new("--num2") { Required = true };

        Command command = new("calculate", "Calculate the sum of two numbers")
        {
            num1Option,
            num2Option
        };
        command.SetAction(result =>
        {
            int num1 = result.GetValue(num1Option);
            int num2 = result.GetValue(num2Option);
            Console.WriteLine($"The sum is: {num1 + num2}");
        });

        RootCommand rootCommand = new("Example calculator");
        rootCommand.Subcommands.Add(command);
        return rootCommand.Parse(args).Invoke();
    }
}
Copied!

Execution

myapp.exe calculate --num1 5 --num2 10
Copied!

The output will be:

The sum is: 15
Copied!

In this case, System.CommandLine automatically converts the values of --num1 and --num2 to integers. If any value is invalid, it displays an error before executing the action.

Command autocompletion

An advanced feature of System.CommandLine is command autocompletion. This feature allows users to get automatic suggestions while typing commands and options on the command line. This is useful for improving usability and user experience.

To enable autocompletion, you need to configure the corresponding functionality in the root command and its subcommands, in addition to ensuring that the terminal used supports this feature.

Copied!