Как стать автором
Обновить
157.77
Рейтинг
Microsoft
Microsoft — мировой лидер в области ПО и ИТ-услуг

Парсер командной строки на .NET5

Блог компании Microsoft Программирование *.NET *C# *Открытые данные *

Сегодня мы собираемся показать вам, как начать парсинг аргументов командной строки. Кстати, это один пост из серии статей о .NET 5. У нас есть еще много интересного.

Приложения командной строки, также известные как консольные приложения, - это программы, созданные для использования из оболочки, например cmd или bash. Они существуют с 1960-х годов, задолго до появления Windows, MacOS или любого другого графического пользовательского интерфейса (GUI).

Обычно, когда вы начинаете изучать язык программирования, самый простой и распространенный стартовый пример -- это приложение Hello world. Подобные примеры в основном выводят на консоль только текст «Hello world», используя свои встроенные API. Компьютерное ПО может делать много разных вещей. Иногда у вас будет ввод, который каким-то образом преобразуется в вывод. В нашем примере «Hello world» нет никакого ввода.

Возьмем C#/.Net. Каждый раз, когда вы создаете новое консольное приложение, вы начинаете с файла Program.cs со статическим методом Main, который является точкой входа в ваше приложение:

...
static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
}
...

Очень важной частью этого кода является определение аргумента string[] args. Это определение параметра, которое содержит все аргументы, которые передаются нашему исполняемому файлу во время инициализации нашего процесса. В отличие от C и C++, имя программы не рассматривается как первый аргумент командной строки в массиве args. Если вам нужно это значение, вы можете вызвать Environment.GetCommandLineArgs().

Если вы привыкли к приложениям командной строки, передача аргументов другим приложениям - очень распространенная задача. Да, вы можете вручную проанализировать эти значения, но если у вас есть несколько параметров, это может быть очень подверженным ошибкам кодом (который в любом случае в основном является шаблонным). Это похоже на проблему, которую кто-то уже мог исправить, не так ли? Поэтому, конечно, мы можем найти библиотеку NuGet, которая поможет нам проанализировать эти аргументы. В этой статье я сосредоточусь на CommandLineParser.

CommandLineParser

CommandLineParser - это библиотека с открытым исходным кодом, созданная Эриком Ньютоном и членами сообщества .NET. Она существует с 2005 года и её скачали более 26 миллионов раз! CommandLineParser «предлагает приложениям CLR простой и лаконичный API для управления аргументами командной строки и связанными задачами, такими как определение переключателей, параметров и команд».

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

Вместо того, чтобы создавать еще один пример только для демонстрации этой библиотеки, я буду использовать консольное приложение WinML .NET5, которым я поделился в своем предыдущем посте. Вот исходный код. Начнем с этого и добавим NuGet-пакет CommandLineParser:

Давайте создадим новый класс с именем CommandLineOptions:

using CommandLine;

namespace ImageClassifier
{
    public class CommandLineOptions
    {
        [Value(index: 0, Required = true, HelpText = "Путь к файлу изображения для анализа.")]
        public string Path { get; set; }

        [Option(shortName: 'c', longName: "confidence", Required = false, HelpText = "Minimum confidence.", Default = 0.9f)]
        public float Confidence { get; set; }
    }
}

Это почти все, что нам нужно для использования этой библиотеки. ValueAttribute и OptionAttribute предоставляются пакетом. Я использую именованные параметры, чтобы было ясно, для чего нужен каждый аргумент. Вернемся к нашему методу Program.cs Main, добавим оператор using, чтобы иметь возможность легко использовать классы пакета в этом файле:

using CommandLine;

Давайте изменим тип возвращаемого значения нашего метода Main на Task. Это означает, что любое возвращаемое нами значение int будет возвращено вызывающей стороне нашего процесса, что обычно указывает на успех/неудачу. В этом примере мы просто вернем 0 в случае успеха и любое другое значение, кроме 0, в случае ошибки:

static async Task Main(string[] args)
{
    return await Parser.Default.ParseArguments<CommandLineOptions>(args)
        .MapResult(async (CommandLineOptions opts) =>
        {
            try
            {
                // У нас есть полученные аргументы, поэтому давайте просто передадим их
                return await AnalyzeFileAsync(opts.Path, opts.Confidence);
            }
            catch
            {
                Console.WriteLine("Error!");
                return -3; // Unhandled error
            }
        },
        errs => Task.FromResult(-1)); // Invalid arguments
}

Здесь вы можете увидеть все изменения по сравнению с предыдущей версией кода.

С этими изменениями приложение корректно анализирует наши аргументы. Для нас даже есть страница помощи, созданная автоматически!

Допустим, вы хотите проанализировать изображение, но хотите получить результат, даже если вы не слишком уверены в нем, скажем, с доверием 30%. Теперь это легко сделать с помощью аргумента -c (--confidence). С этим изображением:

Вы можете получить этот результат, используя --confidence:

> .ImageClassifier.exe C:\Users\alzollin\Downloads\NotALion.jpg --confidence 0.3
Image 'C:\Users\alzollin\Downloads\NotALion.jpg' is classified as 'Persian cat'(p=58%).

Заключение

Пакет NuGet CommandLineParser - очень мощный помощник, который упрощает эту часто повторяющуюся задачу до простого декларативного подхода. Кроме того, он даже еще более кастомизируемый, чем я продемонстрировал здесь. Вы можете найти его документацию на их странице GitHub вики.

Теги:
Хабы:
Всего голосов 12: ↑8 и ↓4 +4
Просмотры 5K
Комментарии Комментарии 7

Информация

Дата основания
Местоположение
США
Сайт
www.microsoft.com
Численность
Неизвестно
Дата регистрации