Freigeben über


Definieren von Befehlen, Optionen und Argumenten in der System.CommandLine

Wichtig

System.CommandLine befindet sich derzeit in der VORSCHAU, und diese Dokumentation gilt für Version 2.0 Beta 4. Einige Informationen beziehen sich auf Vorabversionen des Produkts, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.

In diesem Artikel wird erläutert, wie Sie Befehle, Optionen und Argumente in Befehlszeilen-Apps definieren, die mit der Bibliothek System.CommandLine erstellt wurden. Wie Sie eine vollständige Anwendung erstellen, die diese Methoden veranschaulicht, erfahren Sie im Tutorial Erste Schritte mit System.CommandLine.

Anleitungen zum Entwerfen der Befehle, Optionen und Argumente einer Befehlszeilen-App finden Sie unter Entwurfsleitfaden.

Definieren eines Stammbefehls

Jede Befehlszeilen-App hat einen Stammbefehl, der sich auf die ausführbare Datei selbst bezieht. Wenn Sie eine App ohne Unterbefehle, Optionen und Argumente besitzen, ist die einfachste Möglichkeit, Ihren Code aufzurufen, die folgende:

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

Definieren von Unterbefehlen

Befehle können untergeordnete Befehle aufweisen, die als Unterbefehle oder Verben bezeichnet werden, und auf beliebig vielen Ebenen verschachtelt sein. Unterbefehle können Sie wie folgt hinzufügen:

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

Den innersten Unterbefehl in diesem Beispiel können Sie wie folgt aufrufen:

myapp sub1 sub1a

Definieren von Optionen

Eine Befehlshandlermethode weist normalerweise Parameter auf, deren Werte von Befehlszeilenoptionen stammen. Im folgenden Beispiel werden zwei Optionen erstellt und zum Stammbefehl hinzugefügt. Die Optionsnamen enthalten Doppelbindestrichpräfixe, die für POSIX CLIs typisch sind. Der Befehlshandlercode zeigt die Werte dieser Optionen an:

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

Hier sehen Sie ein Beispiel einer Befehlszeileneingabe und die zugehörige Ausgabe für das vorherige Codebeispiel:

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

Globale Optionen

Mit der Methode Add oder AddOption können Sie eine Option nach der anderen zu einem Befehl hinzufügen, wie im vorherigen Beispiel gezeigt. Mit der Methode AddGlobalOption können Sie eine Option zu einem Befehl und rekursiv zu allen Unterbefehlen hinzufügen, wie im folgenden Beispiel gezeigt:

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

Der vorangehende Code fügt --delay als globale Option zum Stammbefehl hinzu, und sie ist im Handler für subCommand1a verfügbar.

Definieren von Argumenten

Argumente werden wie Optionen definiert und zu Befehlen hinzugefügt. Das folgende Beispiel ähnelt dem Beispiel für Optionen, definiert jedoch Argumente statt Optionen:

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

Hier sehen Sie ein Beispiel einer Befehlszeileneingabe und die zugehörige Ausgabe für das vorherige Codebeispiel:

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

Ein Argument, das ohne Standardwert definiert wird, wie messageArgument im vorherigen Beispiel, wird als erforderliches Argument behandelt. Wenn solch ein erforderliches Argument nicht angegeben wird, wird eine Fehlermeldung angezeigt und der Befehlshandler wird nicht aufgerufen.

Definieren von Aliassen

Befehle und Optionen unterstützen Aliasse. Um einen Alias zu einer Option hinzuzufügen, rufen Sie AddAlias auf:

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

Mit diesem Alias führen die folgenden Befehle zum selben Ergebnis:

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

Befehlsaliasse funktionieren auf dieselbe Weise.

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

Durch diesen Code führen die beiden Befehle zum selben Ergebnis:

myapp serialize
myapp serialise

Wir empfehlen, nicht zu viele Optionsaliasse zu definieren und bestimmte Aliasse komplett zu vermeiden. Weitere Informationen finden Sie unter Kurzform-Aliasse.

Erforderliche Optionen

Um eine Option als erforderlich zu kennzeichnen, legen Sie seine Eigenschaft IsRequired auf true fest, wie im folgenden Beispiel gezeigt:

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

Im Abschnitt zu Optionen der Befehlshilfe wird angegeben, dass die Option erforderlich ist:

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

Wenn der Befehl für diese Beispiel-App --endpoint nicht enthält, wird eine Fehlermeldung angezeigt und der Befehlshandler wird nicht aufgerufen:

Option '--endpoint' is required.

Wenn eine erforderliche Option einen Standardwert hat, muss sie nicht im Befehl angegeben werden. In diesem Fall gilt der Standardwert als Wert für die erforderliche Option.

Ausgeblendete Befehle, Optionen und Argumente

Möglicherweise möchten Sie einen Befehl, eine Option oder ein Argument zwar unterstützen, der Befehl, die Option oder das Argument soll aber nicht einfach zu finden sein, beispielsweise, weil es sich um eine veraltete, administrative oder eine Previewfunktion handelt. Mit der Eigenschaft IsHidden können Sie verhindern, dass Benutzer solche Funktionen mit der Vervollständigung mit der Tabulatortaste oder über die Hilfe finden, wie im folgenden Beispiel gezeigt:

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

Im Abschnitt zu Optionen der Befehlshilfe für dieses Beispiel wird die Option --endpoint dann nicht aufgeführt.

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

Festlegen der Argumentarität

Mit der Eigenschaft Arity können Sie die Argumentarität explizit festlegen. In den meisten Fällen ist dies jedoch nicht nötig. System.CommandLine bestimmt automatisch die Argumentarität basierend auf dem Argumenttyp:

Argumenttyp Standard-Argumentarität
Boolean ArgumentArity.ZeroOrOne
Auflistungstypen ArgumentArity.ZeroOrMore
Alle anderen ArgumentArity.ExactlyOne

Mehrere Argumente

Wenn Sie einen Befehl aufrufen, können Sie standardmäßig einen Optionsnamen wiederholen, um mehrere Argumente für eine Option anzugeben, deren maximale Argumentarität größer als 1 ist.

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

Um mehrere Argumente zuzulassen, ohne dass der Optionsname wiederholt wird, legen Sie Option.AllowMultipleArgumentsPerToken auf true fest. Mit dieser Einstellung können Sie den folgenden Befehl eingeben.

myapp --items one two three

Dieselbe Einstellung hat eine andere Auswirkung, wenn die maximale Argumentarität 1 ist. Dann können Sie eine Option wiederholen, es wird aber nur der letzte Wert im Befehl verwendet. Im folgenden Beispiel wird der Wert three an die App übergeben.

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

Auflisten gültiger Argumentwerte

Um eine Liste der gültigen Werte für eine Option oder ein Argument anzugeben, legen Sie eine Enumeration als Optionstyp fest oder verwenden Sie FromAmong, wie im folgenden Beispiel gezeigt:

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

Hier sehen Sie ein Beispiel einer Befehlszeileneingabe und die zugehörige Ausgabe für das vorherige Codebeispiel:

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

Im Abschnitt zu Optionen der Befehlshilfe werden die gültigen Werte aufgeführt:

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

Überprüfung von Optionen und Argumenten

Informationen zu der Argumentüberprüfung und deren Anpassung finden Sie in den folgenden Abschnitten des Artikels So binden Sie Argumente an Handler in System.CommandLine:

Weitere Informationen