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: