Partager via


Guide pratique pour définir des commandes, des options et des arguments dans System.CommandLine

Important

System.CommandLine est actuellement une PRÉVERSION et cette documentation concerne la version 2.0 beta 4. Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.

Cet article explique comment définir des commandes, des options et des arguments dans les applications en ligne de commande générées avec la bibliothèque System.CommandLine. Pour générer une application complète illustrant ces techniques, consultez le tutoriel Bien démarrer avecSystem.CommandLine.

Pour obtenir des conseils d’aide sur la conception des commandes, des options et des arguments d’une application en ligne de commande, consultez les Conseils d’aide pour la conception.

Définir une commande racine

Chaque application en ligne de commande a une commande racine, qui fait référence au fichier exécutable lui-même. Le cas le plus simple pour appeler votre code, si vous avez une application sans sous-commandes, options ou arguments, se présente comme ceci :

using System.CommandLine;

class Program
{
    static async Task Main(string[] args)
    {
        var rootCommand = new RootCommand("Sample command-line app");

        rootCommand.SetHandler(() =>
        {
            Console.WriteLine("Hello world!");
        });

        await rootCommand.InvokeAsync(args);
    }
}

Définir des sous-commandes

Les commandes peuvent avoir des commandes enfants, appelées sous-commandes ou verbes, et elles peuvent imbriquer autant de niveaux que vous le souhaitez. Vous pouvez ajouter des sous-commandes, comme le montre l’exemple suivant :

var rootCommand = new RootCommand();
var sub1Command = new Command("sub1", "First-level subcommand");
rootCommand.Add(sub1Command);
var sub1aCommand = new Command("sub1a", "Second level subcommand");
sub1Command.Add(sub1aCommand);

La sous-commande la plus intérieure dans cet exemple peut être appelée comme ceci :

myapp sub1 sub1a

Définir des options

Une méthode de gestionnaire de commandes a généralement des paramètres. Les valeurs peuvent provenir d’options de ligne de commande. L’exemple suivant crée deux options et les ajoute à la commande racine. Les noms d’options contiennent des préfixes avec trait d’union double, ce qui est propre aux interfaces CLI POSIX. Le code du gestionnaire de commandes affiche les valeurs de ces options :

var delayOption = new Option<int>
    (name: "--delay",
    description: "An option whose argument is parsed as an int.",
    getDefaultValue: () => 42);
var messageOption = new Option<string>
    ("--message", "An option whose argument is parsed as a string.");

var rootCommand = new RootCommand();
rootCommand.Add(delayOption);
rootCommand.Add(messageOption);

rootCommand.SetHandler((delayOptionValue, messageOptionValue) =>
    {
        Console.WriteLine($"--delay = {delayOptionValue}");
        Console.WriteLine($"--message = {messageOptionValue}");
    },
    delayOption, messageOption);

Voici un exemple d’entrée de ligne de commande et de sortie résultante pour l’exemple de code précédent :

myapp --delay 21 --message "Hello world!"
--delay = 21
--message = Hello world!

Options globales

Pour ajouter une option à une seule commande à la fois, utilisez la méthode Add ou AddOption, comme le montre l’exemple précédent. Pour ajouter une option à une commande, et de manière récursive à toutes ses sous-commandes, utilisez la méthode AddGlobalOption, comme le montre l’exemple suivant :

var delayOption = new Option<int>
    ("--delay", "An option whose argument is parsed as an int.");
var messageOption = new Option<string>
    ("--message", "An option whose argument is parsed as a string.");

var rootCommand = new RootCommand();
rootCommand.AddGlobalOption(delayOption);
rootCommand.Add(messageOption);

var subCommand1 = new Command("sub1", "First level subcommand");
rootCommand.Add(subCommand1);

var subCommand1a = new Command("sub1a", "Second level subcommand");
subCommand1.Add(subCommand1a);

subCommand1a.SetHandler((delayOptionValue) =>
    {
        Console.WriteLine($"--delay = {delayOptionValue}");
    },
    delayOption);

await rootCommand.InvokeAsync(args);

Le code précédent ajoute --delay en tant qu’option globale à la commande racine, et est disponible dans le gestionnaire pour subCommand1a.

Définir des arguments

Les arguments sont définis et ajoutés aux commandes, comme les options. L’exemple suivant est similaire à l’exemple relatif aux options. Toutefois, il définit des arguments à la place d’options :

var delayArgument = new Argument<int>
    (name: "delay",
    description: "An argument that is parsed as an int.",
    getDefaultValue: () => 42);
var messageArgument = new Argument<string>
    ("message", "An argument that is parsed as a string.");

var rootCommand = new RootCommand();
rootCommand.Add(delayArgument);
rootCommand.Add(messageArgument);

rootCommand.SetHandler((delayArgumentValue, messageArgumentValue) =>
    {
        Console.WriteLine($"<delay> argument = {delayArgumentValue}");
        Console.WriteLine($"<message> argument = {messageArgumentValue}");
    },
    delayArgument, messageArgument);

await rootCommand.InvokeAsync(args);

Voici un exemple d’entrée de ligne de commande et de sortie résultante pour l’exemple de code précédent :

myapp 42 "Hello world!"
<delay> argument = 42
<message> argument = Hello world!

Un argument défini sans valeur par défaut, par exemple messageArgument dans l’exemple précédent, est traité en tant qu’argument obligatoire. Un message d’erreur s’affiche et le gestionnaire de commandes n’est pas appelé, si un argument obligatoire n’est pas fourni.

Définir des alias

Les commandes et les options prennent en charge les alias. Vous pouvez ajouter un alias à une option en appelant AddAlias :

var option = new Option("--framework");
option.AddAlias("-f");

Avec cet alias, les lignes de commande suivantes sont équivalentes :

myapp -f net6.0
myapp --framework net6.0

Les alias de commande fonctionnent de la même manière.

var command = new Command("serialize");
command.AddAlias("serialise");

Ce code rend les lignes de commande suivantes équivalentes :

myapp serialize
myapp serialise

Nous vous recommandons de réduire le nombre d’alias d’option que vous définissez, et d’éviter de définir certains alias en particulier. Pour plus d’informations, consultez Alias courts.

Options obligatoires

Pour rendre une option obligatoire, affectez la valeur true à sa propriété IsRequired, comme le montre l’exemple suivant :

var endpointOption = new Option<Uri>("--endpoint") { IsRequired = true };
var command = new RootCommand();
command.Add(endpointOption);

command.SetHandler((uri) =>
    {
        Console.WriteLine(uri?.GetType());
        Console.WriteLine(uri?.ToString());
    },
    endpointOption);

await command.InvokeAsync(args);

La section des options de l’aide de la commande indique que l’option est obligatoire :

Options:
  --endpoint <uri> (REQUIRED)
  --version               Show version information
  -?, -h, --help          Show help and usage information

Si la ligne de commande de cet exemple d’application n’inclut pas --endpoint, un message d’erreur s’affiche et le gestionnaire de commandes n’est pas appelé :

Option '--endpoint' is required.

Si une option obligatoire a une valeur par défaut, cette option n’a pas besoin d’être spécifiée sur la ligne de commande. Dans ce cas, la valeur par défaut fournit la valeur d’option nécessaire.

Commandes, options et arguments masqués

Vous pouvez être amené à prendre en charge une commande, une option ou un argument, en évitant de le rendre facile à découvrir. Par exemple, il peut s’agir d’une fonctionnalité dépréciée, d’administration ou d’évaluation. Utilisez la propriété IsHidden pour empêcher les utilisateurs de découvrir ces fonctionnalités via la complétion par tabulation ou l’aide, comme le montre l’exemple suivant :

var endpointOption = new Option<Uri>("--endpoint") { IsHidden = true };
var command = new RootCommand();
command.Add(endpointOption);

command.SetHandler((uri) =>
    {
        Console.WriteLine(uri?.GetType());
        Console.WriteLine(uri?.ToString());
    },
    endpointOption);

await command.InvokeAsync(args);

La section des options de l’aide de la commande de cet exemple omet l’option --endpoint.

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

Définir l’arité des arguments

Vous pouvez définir explicitement l’arité des arguments à l’aide de la propriété Arity, mais dans la plupart des cas, cela n’est pas nécessaire. System.CommandLine détermine automatiquement l’arité des arguments en fonction du type d’argument :

Type d’argument Arité par défaut
Boolean ArgumentArity.ZeroOrOne
Types de collections ArgumentArity.ZeroOrMore
Tout le reste ArgumentArity.ExactlyOne

Arguments multiples

Par défaut, quand vous appelez une commande, vous pouvez répéter un nom d’option pour spécifier plusieurs arguments d’une option dont l’arité maximale est supérieure à un.

myapp --items one --items two --items three

Pour autoriser plusieurs arguments sans répéter le nom de l’option, affectez la valeur true à Option.AllowMultipleArgumentsPerToken. Ce paramètre vous permet d’entrer la ligne de commande suivante.

myapp --items one two three

Le même paramètre a un effet différent si l’arité maximale des arguments est 1. Cela vous permet de répéter une option, mais seule la dernière valeur de la ligne est acceptée. Dans l’exemple suivant, la valeur three est passée à l’application.

myapp --item one --item two --item three

Lister les valeurs d’arguments valides

Si vous souhaitez indiquer une liste de valeurs valides pour une option ou un argument, spécifiez un enum en tant que type d’option, ou utilisez FromAmong, comme le montre l’exemple suivant :

var languageOption = new Option<string>(
    "--language",
    "An option that that must be one of the values of a static list.")
        .FromAmong(
            "csharp",
            "fsharp",
            "vb",
            "pwsh",
            "sql");

Voici un exemple d’entrée de ligne de commande et de sortie résultante pour l’exemple de code précédent :

myapp --language not-a-language
Argument 'not-a-language' not recognized. Must be one of:
        'csharp'
        'fsharp'
        'vb'
        'pwsh'
        'sql'

La section des options de l’aide de la commande montre les valeurs valides :

Options:
  --language <csharp|fsharp|vb|pwsh|sql>  An option that must be one of the values of a static list.
  --version                               Show version information
  -?, -h, --help                          Show help and usage information

Validation des options et des arguments

Pour plus d’informations sur la validation des arguments et leur personnalisation, consultez les sections suivantes de l’article Liaison de paramètres :

Voir aussi