Определение команд, параметров и аргументов в System.CommandLine

Внимание

System.CommandLine в настоящее время находится в предварительной версии, и эта документация предназначена для версии 2.0 бета-версии 4. Некоторые сведения относятся к предварительному выпуску продукта, который может быть существенно изменен до его выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В этой статье объясняется, как определить команды, параметры и аргументы в приложениях командной строки, созданных с помощью библиотекиSystem.CommandLine. Чтобы создать полное приложение, которое иллюстрирует эти методы, ознакомьтесь с System.CommandLineруководством по началу работы.

Инструкции по проектированию команд, параметров и аргументов приложения командной строки см . в руководстве по проектированию.

Определение корневой команды

Каждое приложение командной строки имеет корневую команду, которая ссылается на сам исполняемый файл. Самый простой случай вызова кода, если у вас есть приложение без вложенных команд, параметров или аргументов, будет выглядеть следующим образом:

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

Определение вложенных команд

Команды могут содержать дочерние команды, известные как вложенные команды или команды, и они могут вложить столько уровней, сколько вам нужно. Вы можете добавить вложенные комманды, как показано в следующем примере:

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

Самый внутренний подкоманда в этом примере можно вызвать следующим образом:

myapp sub1 sub1a

Определение параметров

Обычно метод обработчика команд имеет параметры, а значения могут поступать из параметров командной строки. В следующем примере создаются два варианта и они добавляются в корневую команду. Имена параметров включают префиксы двойного дефиса, типичные для CLIS POSIX. Код обработчика команд отображает значения этих параметров:

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

Ниже приведен пример ввода командной строки и результирующий результат для предыдущего примера кода:

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

Глобальные параметры

Чтобы добавить параметр к одной команде одновременно, используйте Add метод или AddOption метод, как показано в предыдущем примере. Чтобы добавить параметр в команду и рекурсивно ко всем его подкомандам, используйте AddGlobalOption метод, как показано в следующем примере:

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

Приведенный выше код добавляется --delay в качестве глобального параметра в корневую команду, и она доступна в обработчике subCommand1a.

Определение аргументов

Аргументы определяются и добавляются в команды, такие как параметры. Следующий пример похож на пример параметров, но определяет аргументы вместо параметров:

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

Ниже приведен пример ввода командной строки и результирующий результат для предыдущего примера кода:

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

Аргумент, который определен без значения по умолчанию, например messageArgument в предыдущем примере, рассматривается как обязательный аргумент. Отображается сообщение об ошибке, и обработчик команд не вызывается, если обязательный аргумент не указан.

Определение псевдонимов

Обе команды и параметры поддерживают псевдонимы. Вы можете добавить псевдоним в параметр, вызвав:AddAlias

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

Учитывая этот псевдоним, следующие командные строки эквивалентны:

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

Псевдонимы команд работают так же.

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

Этот код эквивалентен следующим командам:

myapp serialize
myapp serialise

Рекомендуется свести к минимуму количество определенных псевдонимов параметров, которые вы определили, и избежать определения определенных псевдонимов в частности. Дополнительные сведения см. в разделе "Кратковременные псевдонимы".

Обязательные параметры

Чтобы сделать параметр обязательным, задайте для свойства значение IsRequiredtrue, как показано в следующем примере:

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

Раздел параметров справки команды указывает, что требуется параметр:

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

Если в командной строке этого примера приложения нет --endpoint, отображается сообщение об ошибке, а обработчик команд не вызывается:

Option '--endpoint' is required.

Если обязательный параметр имеет значение по умолчанию, параметр не должен быть указан в командной строке. В этом случае значение по умолчанию предоставляет требуемое значение параметра.

Скрытые команды, параметры и аргументы

Возможно, вы хотите поддерживать команду, параметр или аргумент, но избежать упрощения обнаружения. Например, это может быть нерекомендуемая или административная или предварительная версия функции. IsHidden Используйте свойство, чтобы запретить пользователям обнаруживать такие функции с помощью завершения вкладки или справки, как показано в следующем примере:

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

Раздел параметров команды этого примера позволяет не использовать --endpoint этот параметр.

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

Установка arity аргумента

Вы можете явно задать arity аргумента Arity с помощью свойства, но в большинстве случаев это необязательно. System.CommandLine автоматически определяет arity аргумента на основе типа аргумента:

Тип аргумента Arity по умолчанию
Boolean ArgumentArity.ZeroOrOne
Типы коллекций ArgumentArity.ZeroOrMore
В любом другом месте ArgumentArity.ExactlyOne

Несколько аргументов

По умолчанию при вызове команды можно повторить имя параметра, чтобы указать несколько аргументов для параметра с максимальным числом arity больше одного.

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

Чтобы разрешить несколько аргументов без повторения имени параметра, задайте для trueпараметра Option.AllowMultipleArgumentsPerToken значение . Этот параметр позволяет ввести следующую командную строку.

myapp --items one two three

Тот же параметр имеет другой эффект, если максимальное число аргументов равно 1. Он позволяет повторять параметр, но принимает только последнее значение в строке. В следующем примере значение three будет передано приложению.

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

Перечисление допустимых значений аргументов

Чтобы указать список допустимых значений для параметра или аргумента, укажите перечисление в качестве типа параметра или использования FromAmong, как показано в следующем примере:

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

Ниже приведен пример ввода командной строки и результирующий результат для предыдущего примера кода:

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

В разделе параметров команды показаны допустимые значения:

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

Проверка параметров и аргументов

Сведения о проверке аргументов и его настройке см. в следующих разделах статьи о привязке параметров:

См. также