How to define commands, options, and arguments in (Jak definiować polecenia, opcje i argumenty) System.CommandLine
Ważne
System.CommandLine
jest obecnie dostępna w wersji zapoznawczej, a ta dokumentacja dotyczy wersji 2.0 beta 4.
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed jego wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
W tym artykule wyjaśniono, jak definiować polecenia, opcje i argumenty w aplikacjach wiersza polecenia utworzonych za System.CommandLine
pomocą biblioteki. Aby utworzyć pełną aplikację, która ilustruje te techniki, zobacz samouczek Wprowadzenie do System.CommandLineusługi .
Aby uzyskać wskazówki dotyczące projektowania poleceń, opcji i argumentów aplikacji wiersza polecenia, zobacz Wskazówki dotyczące projektowania.
Definiowanie polecenia głównego
Każda aplikacja wiersza polecenia ma polecenie główne, które odwołuje się do samego pliku wykonywalnego. Najprostszym przypadkiem wywoływania kodu, jeśli masz aplikację bez poleceń podrzędnych, opcji lub argumentów, będzie wyglądać następująco:
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);
}
}
Definiowanie podpolecenia
Polecenia mogą zawierać polecenia podrzędne, znane jako podpolecenia lub czasowniki, i mogą zagnieżdżać dowolną liczbę poziomów. Możesz dodać podpolecenia, jak pokazano w poniższym przykładzie:
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);
Najbardziej wewnętrzne podpolecenia w tym przykładzie można wywołać w następujący sposób:
myapp sub1 sub1a
Definiowanie opcji
Metoda obsługi poleceń zwykle zawiera parametry, a wartości mogą pochodzić z opcji wiersza polecenia. Poniższy przykład tworzy dwie opcje i dodaje je do głównego polecenia. Nazwy opcji obejmują prefiksy podwójnego łącznika, które są typowe dla interfejsów WIERSZA POLECENIA POSIX. Kod programu obsługi poleceń wyświetla wartości tych opcji:
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);
Oto przykład danych wejściowych wiersza polecenia i wynikowych danych wyjściowych dla poprzedniego przykładowego kodu:
myapp --delay 21 --message "Hello world!"
--delay = 21
--message = Hello world!
Opcje globalne
Aby dodać opcję do jednego polecenia jednocześnie, użyj Add
metody lub AddOption
, jak pokazano w poprzednim przykładzie. Aby dodać opcję do polecenia i cyklicznie do wszystkich poleceń podrzędnych, użyj AddGlobalOption
metody , jak pokazano w poniższym przykładzie:
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);
Powyższy kod dodaje --delay
jako opcję globalną do polecenia głównego i jest dostępny w procedurze obsługi dla programu subCommand1a
.
Definiowanie argumentów
Argumenty są definiowane i dodawane do poleceń, takich jak opcje. Poniższy przykład przypomina przykład opcji, ale definiuje argumenty zamiast opcji:
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);
Oto przykład danych wejściowych wiersza polecenia i wynikowych danych wyjściowych dla poprzedniego przykładowego kodu:
myapp 42 "Hello world!"
<delay> argument = 42
<message> argument = Hello world!
Argument zdefiniowany bez wartości domyślnej, taki jak messageArgument
w poprzednim przykładzie, jest traktowany jako argument wymagany. Zostanie wyświetlony komunikat o błędzie, a program obsługi poleceń nie jest wywoływany, jeśli nie podano wymaganego argumentu.
Definiowanie aliasów
Oba polecenia i opcje obsługują aliasy. Alias można dodać do opcji, wywołując polecenie AddAlias
:
var option = new Option("--framework");
option.AddAlias("-f");
Biorąc pod uwagę ten alias, następujące wiersze polecenia są równoważne:
myapp -f net6.0
myapp --framework net6.0
Aliasy poleceń działają w taki sam sposób.
var command = new Command("serialize");
command.AddAlias("serialise");
Ten kod sprawia, że następujące wiersze polecenia są równoważne:
myapp serialize
myapp serialise
Zalecamy zminimalizowanie liczby zdefiniowanych aliasów opcji i unikanie definiowania określonych aliasów. Aby uzyskać więcej informacji, zobacz Aliasy krótkich formularzy.
Wymagane opcje
Aby ustawić wymaganą opcję, ustaw jej IsRequired
właściwość na true
, jak pokazano w poniższym przykładzie:
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);
Sekcja opcji pomocy polecenia wskazuje, że wymagana jest opcja:
Options:
--endpoint <uri> (REQUIRED)
--version Show version information
-?, -h, --help Show help and usage information
Jeśli wiersz polecenia dla tej przykładowej aplikacji nie zawiera --endpoint
, zostanie wyświetlony komunikat o błędzie i program obsługi poleceń nie jest wywoływany:
Option '--endpoint' is required.
Jeśli wymagana opcja ma wartość domyślną, opcja nie musi być określona w wierszu polecenia. W takim przypadku wartość domyślna udostępnia wymaganą wartość opcji.
Ukryte polecenia, opcje i argumenty
Możesz chcieć obsługiwać polecenie, opcję lub argument, ale unikaj łatwego odnajdywania. Na przykład może to być przestarzała funkcja administracyjna lub zapoznawcza. IsHidden Użyj właściwości , aby uniemożliwić użytkownikom odnajdywanie takich funkcji przy użyciu uzupełniania kart lub pomocy, jak pokazano w poniższym przykładzie:
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);
Sekcja opcji polecenia tego przykładu pomaga pominąć --endpoint
opcję.
Options:
--version Show version information
-?, -h, --help Show help and usage information
Ustawianie arity argumentu
Można jawnie ustawić arity argumentów Arity
przy użyciu właściwości , ale w większości przypadków nie jest to konieczne. System.CommandLine
automatycznie określa arity argumentu na podstawie typu argumentu:
Typ argumentu | Domyślna arity |
---|---|
Boolean |
ArgumentArity.ZeroOrOne |
Typy kolekcji | ArgumentArity.ZeroOrMore |
Wszystko | ArgumentArity.ExactlyOne |
Wiele argumentów
Domyślnie podczas wywoływania polecenia można powtórzyć nazwę opcji, aby określić wiele argumentów dla opcji, która ma maksymalną wartość arity większą niż jedną.
myapp --items one --items two --items three
Aby zezwolić na wiele argumentów bez powtarzania nazwy opcji, ustaw wartość Option.AllowMultipleArgumentsPerTokentrue
. To ustawienie umożliwia wprowadzenie następującego wiersza polecenia.
myapp --items one two three
To samo ustawienie ma inny wpływ, jeśli maksymalna wartość arity argumentu wynosi 1. Umożliwia powtórzenie opcji, ale przyjmuje tylko ostatnią wartość w wierszu. W poniższym przykładzie wartość three
zostanie przekazana do aplikacji.
myapp --item one --item two --item three
Wyświetlanie listy prawidłowych wartości argumentów
Aby określić listę prawidłowych wartości dla opcji lub argumentu, określ wyliczenie jako typ opcji lub użyj polecenia FromAmong, jak pokazano w poniższym przykładzie:
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");
Oto przykład danych wejściowych wiersza polecenia i wynikowych danych wyjściowych dla poprzedniego przykładowego kodu:
myapp --language not-a-language
Argument 'not-a-language' not recognized. Must be one of:
'csharp'
'fsharp'
'vb'
'pwsh'
'sql'
Sekcja opcji pomocy polecenia zawiera prawidłowe wartości:
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
Weryfikacja opcji i argumentów
Aby uzyskać informacje o weryfikacji argumentów i sposobie jego dostosowywania, zobacz następujące sekcje w artykule Powiązanie parametrów: