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.CommandLineThis 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();
}
}Code explanation
-
Defining a
RootCommand: ARootCommandis the main command that will handle command-line arguments. Here, we created a root command with a--nameoption, which takes astringvalue and is used to greet the user. -
Assigning an action:
SetActiondefines what happens when the command is executed. The action retrieves the value of--namefrom the parse result. -
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 CarlosThe output will be:
Hello, Carlos!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();
}
}Code explanation
-
Defining subcommands: We added two subcommands to the
RootCommand:greetandfarewell, each with a--nameoption. -
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 CarlosThe output will be:
Hello, Carlos!If we run the farewell subcommand:
myapp.exe farewell --name CarlosThe output will be:
Goodbye, Carlos!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();
}
}Execution
myapp.exe calculate --num1 5 --num2 10The output will be:
The sum is: 15In 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.