Sdílet prostřednictvím


Jak definovat příkazy, možnosti a argumenty v System.CommandLine

Důležité

System.CommandLine je aktuálně ve verzi PREVIEW a tato dokumentace je určená pro verzi 2.0 beta 4. Některé informace se týkají předběžné verze produktu, který může být podstatně změněn před vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Tento článek vysvětluje, jak definovat příkazy, možnosti a argumenty v aplikacích příkazového řádku vytvořených pomocí System.CommandLine knihovny. Pokud chcete vytvořit kompletní aplikaci, která ilustruje tyto techniky, prohlédnou si kurz Začínáme s System.CommandLine.

Pokyny k návrhu příkazů, možností a argumentů aplikace příkazového řádku najdete v pokynech k návrhu.

Definování kořenového příkazu

Každá aplikace příkazového řádku má kořenový příkaz, který odkazuje na samotný spustitelný soubor. Nejjednodušším případem pro vyvolání kódu, pokud máte aplikaci bez dílčích příkazů, možností nebo argumentů, by vypadala takto:

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

Definování dílčích příkazů

Příkazy můžou mít podřízené příkazy, označované jako dílčí příkazy nebo příkazy, a můžou vnořit tolik úrovní, kolik potřebujete. Můžete přidat dílčí příkazy, jak je znázorněno v následujícím příkladu:

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

Nejvnitřnější podpříkaz v tomto příkladu lze vyvolat takto:

myapp sub1 sub1a

Definování možností

Metoda obslužné rutiny příkazu má obvykle parametry a hodnoty můžou pocházet z možností příkazového řádku. Následující příklad vytvoří dvě možnosti a přidá je do kořenového příkazu. Názvy možností zahrnují předpony dvojitých pomlček, které jsou typické pro rozhraní CLIs POSIX. Kód obslužné rutiny příkazu zobrazí hodnoty těchto možností:

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

Tady je příklad vstupu příkazového řádku a výsledného výstupu pro předchozí ukázkový kód:

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

Globální možnosti

Pokud chcete přidat možnost k jednomu příkazu najednou, použijte Add metodu nebo AddOption metodu, jak je znázorněno v předchozím příkladu. Pokud chcete do příkazu přidat možnost a rekurzivně do všech jejích dílčích příkazů, použijte metodu AddGlobalOption , jak je znázorněno v následujícím příkladu:

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

Předchozí kód přidá --delay do kořenového příkazu globální možnost a je k dispozici v obslužné rutině pro subCommand1a.

Definování argumentů

Argumenty jsou definovány a přidány do příkazů, jako jsou možnosti. Následující příklad je podobný příkladu možností, ale definuje argumenty místo možností:

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

Tady je příklad vstupu příkazového řádku a výsledného výstupu pro předchozí ukázkový kód:

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

Argument definovaný bez výchozí hodnoty, například messageArgument v předchozím příkladu, je považován za povinný argument. Zobrazí se chybová zpráva a obslužná rutina příkazu není volána, pokud není zadán požadovaný argument.

Definování aliasů

Aliasy podporují příkazy i možnosti. Alias můžete přidat k možnosti voláním AddAlias:

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

Vzhledem k tomuto aliasu jsou následující příkazové řádky ekvivalentní:

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

Aliasy příkazů fungují stejným způsobem.

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

Tento kód vytvoří ekvivalentní následující příkazové řádky:

myapp serialize
myapp serialise

Doporučujeme minimalizovat počet aliasů možností, které definujete, a vyhnout se definování určitých aliasů zejména. Další informace naleznete v tématu Zkratky aliasů.

Požadované možnosti

Pokud chcete nastavit požadovanou možnost, nastavte její IsRequired vlastnost na true, jak je znázorněno v následujícím příkladu:

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

Část možnosti nápovědy k příkazu indikuje, že je tato možnost povinná:

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

Pokud příkazový řádek pro tuto ukázkovou aplikaci neobsahuje --endpoint, zobrazí se chybová zpráva a obslužná rutina příkazu se nevolá:

Option '--endpoint' is required.

Pokud má požadovaná možnost výchozí hodnotu, nemusí být na příkazovém řádku zadána možnost. V takovém případě výchozí hodnota poskytuje požadovanou hodnotu možnosti.

Skryté příkazy, možnosti a argumenty

Můžete chtít podporovat příkaz, možnost nebo argument, ale vyhnout se snadnému zjišťování. Může to být například zastaralá nebo zastaralá nebo funkce ve verzi Preview. IsHidden Pomocí vlastnosti můžete uživatelům zabránit ve zjišťování těchto funkcí pomocí dokončování tabulátoru nebo nápovědy, jak je znázorněno v následujícím příkladu:

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

Část Možnosti v nápovědě k příkazu tohoto příkladu --endpoint tuto možnost vynechá.

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

Nastavení argumentu arity

Pomocí vlastnosti můžete explicitně nastavit arity argumentů Arity, ale ve většině případů to není nutné. System.CommandLine automaticky určuje arity argumentu na základě typu argumentu:

Typ argumentu Výchozí arity
Boolean ArgumentArity.ZeroOrOne
Typy kolekcí ArgumentArity.ZeroOrMore
Všechno ostatní ArgumentArity.ExactlyOne

Více argumentů

Ve výchozím nastavení můžete při volání příkazu opakovat název možnosti a zadat více argumentů pro možnost, která má maximální počet znaků větší než jeden.

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

Chcete-li povolit více argumentů bez opakování názvu možnosti, nastavte Option.AllowMultipleArgumentsPerToken na truehodnotu . Toto nastavení umožňuje zadat následující příkazový řádek.

myapp --items one two three

Stejné nastavení má jiný účinek, pokud je maximální argument arity 1. Umožňuje opakovat možnost, ale přebírá pouze poslední hodnotu na řádku. V následujícím příkladu by se hodnota three předala aplikaci.

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

Výpis platných hodnot argumentů

Chcete-li zadat seznam platných hodnot pro možnost nebo argument, zadejte výčt jako typ možnosti nebo použijte FromAmong, jak je znázorněno v následujícím příkladu:

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

Tady je příklad vstupu příkazového řádku a výsledného výstupu pro předchozí ukázkový kód:

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

V části Možnosti nápovědy k příkazům se zobrazují platné hodnoty:

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

Ověření možností a argumentů

Informace o ověření argumentu a o tom, jak ho přizpůsobit, najdete v následujících částech článku vazby parametru:

Viz také