Getting started with System.CommandLine
Posted: (EET/GMT+2)
When starting to write simple CLI tools, the needs are often modest in the beginning. But once the application grows, you will notice that you need command-line arguments, switches, and a help screen. If you are building console application with C#, you can parse command-line arguments manually, but it is usually nicer to use a real command-line parser.
Microsoft's newish System.CommandLine NuGet package gives you commands, options, arguments, validation, and generated help text. To use it, start by adding the package to your project:
dotnet add package System.CommandLine
Here is a minimal example:
using System.CommandLine;
Option<string> nameOption =
new("--name", "-n")
{
Description = "Name to greet",
DefaultValueFactory = _ => "World"
};
Option<bool> shoutOption =
new("--shout")
{
Description = "Print the greeting in uppercase"
};
RootCommand rootCommand =
new("Small demo application using System.CommandLine");
rootCommand.Options.Add(nameOption);
rootCommand.Options.Add(shoutOption);
rootCommand.SetAction(parseResult =>
{
string name =
parseResult.GetValue(nameOption) ?? "World";
bool shout =
parseResult.GetValue(shoutOption);
string message =
$"Hello, {name}!";
if (shout)
{
message =
message.ToUpperInvariant();
}
Console.WriteLine(message);
return 0;
});
// run the application and get the exit code
int exitCode = rootCommand.Parse(args).Invoke();
return exitCode;
Now run the application and pass arguments after -- when using dotnet run:
dotnet run -- --name "Ada"
Output:
Hello, Ada!
The short alias works too:
dotnet run -- -n "Ada" --shout
Output:
HELLO, ADA!
One of the nice things about System.CommandLine is that help text comes for
free. If you run your application with the --help parameter, like this:
dotnet run -- --help
...then the output will look roughly like this:
Description: Small demo application using System.CommandLine Usage: MyTool [options] Options: --name, -n <name> Name to greet [default: World] --shout Print the greeting in uppercase -?, -h, --help Show help and usage information --version Show version information
This is already better than many hand-written argument parsers.So, there are some good reasons why System.CommandLine is useful:
- options can be strongly typed
- short and long aliases are easy to define
- default values are visible in help output
- invalid arguments are handled consistently
--helpworks without writing your own help screen.
For small internal tools, this keeps the code clean. For larger command-line applications, it gives users a more professional interface. Just spend a moment to write good option descriptions, as those descriptions become your
--help output.
Also remember to return an exit code from the command action. Returning 0 usually means success. Non-zero values are useful when the tool is used from scripts or build pipelines. For instance:
rootCommand.SetAction(parseResult =>
{
Console.WriteLine("Done.");
return 0;
});
The System.CommandLine package is not needed for every console application. If your app has no arguments or just very few, plain args processing is enough. Adding packages for just for the sake of it is unwise in the long run. Here's a nice syntax tutorial about this package.