繁体   English   中英

解析 C# 中的命令行参数/选项

[英]Parse command line arguments/options in C#

我有一个带有一些 arguments 和选项的控制台应用程序,所以我想使用免费的第三方库。

为此,我找到了两个库: NDesk.OptionsCommand Line Parser Library

最后我决定使用 Command Line Parser Library,因为它使用属性更清晰,所以我下载了它并添加了对它的引用。

问题是,在添加对我的 .NET Framework 3.5 项目的引用时,我得到一个警告图标。 从我下载的上面的页面上,它说兼容性是 .NET Framework 3.5+,所以我知道 3.5 是兼容的,对吗? 如果不是,它的哪个先前版本与 .NET Framework 3.5 兼容?

您也可以使用新的Microsoft CommandLineUtils库。 nuget软件包在这里,但仅适用于.NET Core或Framrwork 4.5.2。 但是您可以下载源代码(仅7个文件)并包含在projet中。 对于Framework 3.5,您只需解决2个编译错误:删除一个额外的方法(使用Tasks)并删除一行(在HandleUnexpectedArg中)。

要使用此库,请在此处找到第一个示例:

static void Main(string[] args)
{
    var cmd = new CommandLineApplication();
    var argAdd = cmd.Option("-a | --add <value>", "Add a new item", CommandOptionType.SingleValue);

    cmd.OnExecute(() =>
    {
        Console.WriteLine(argAdd.Value());
        return 0;
    });

    cmd.HelpOption("-? | -h | --help");
    cmd.Execute(args);            
}

McMaster.Extensions.CommandLineUtils 是我用过的最好的 c# 命令行解析器。 我特别喜欢它很好地支持子命令。

源代码在这里: https://github.com/natemcmaster/CommandLineUtils

dotnet add package McMaster.Extensions.CommandLineUtils

这是一个如何使用属性使用它的简单示例:

using System;
using McMaster.Extensions.CommandLineUtils;

public class Program
{
    public static int Main(string[] args)
        => CommandLineApplication.Execute<Program>(args);

    [Option(Description = "The subject")]
    public string Subject { get; } = "world";

    [Option(ShortName = "n")]
    public int Count { get; } = 1;

    private void OnExecute()
    {
        for (var i = 0; i < Count; i++)
        {
            Console.WriteLine($"Hello {Subject}!");
        }
    }
}

或者您可以使用构建器:

using System;
using McMaster.Extensions.CommandLineUtils;

var app = new CommandLineApplication();

app.HelpOption();

var subject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
subject.DefaultValue = "world";

var repeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
repeat.DefaultValue = 1;

app.OnExecute(() =>
{
    for (var i = 0; i < repeat.ParsedValue; i++)
    {
        Console.WriteLine($"Hello {subject.Value()}!");
    }
});

return app.Execute(args);

微软也一直致力于命令行解析器: https://github.com/do.net/command-line-api但它已经预览了很长时间。

我推荐FluentArgs (请参阅: https : //github.com/kutoga/FluentArgs )。 我认为这很容易使用:

namespace Example
{
    using System;
    using System.Threading.Tasks;
    using FluentArgs;

    public static class Program
    {
        public static Task Main(string[] args)
        {
            return FluentArgsBuilder.New()
                .DefaultConfigsWithAppDescription("An app to convert png files to jpg files.")
                .Parameter("-i", "--input")
                    .WithDescription("Input png file")
                    .WithExamples("input.png")
                    .IsRequired()
                .Parameter("-o", "--output")
                    .WithDescription("Output jpg file")
                    .WithExamples("output.jpg")
                    .IsRequired()
                .Parameter<ushort>("-q", "--quality")
                    .WithDescription("Quality of the conversion")
                    .WithValidation(n => n >= 0 && n <= 100)
                    .IsOptionalWithDefault(50)
                .Call(quality => outputFile => inputFile =>
                {
                    /* ... */
                    Console.WriteLine($"Convert {inputFile} to {outputFile} with quality {quality}...");
                    /* ... */
                    return Task.CompletedTask;
                })
                .ParseAsync(args);
        }
    }
}

github页面上还有许多其他示例。

System.CommandLine可能会成功。 尽管截至 2022 年 11 月,它仍处于测试阶段。 我想 .NET 团队将把它包含在一些即将发布的 .NET 框架版本中。

https://github.com/do.net/runtime/issues/68578 https://www.nuget.org/packages/System.CommandLine

如果您正在寻找第三方库来帮助您解析命令行 arguments 和 C# 中的选项,您可能需要查看TreeBasedCli库。 它是一个 C# 库,旨在简化使用嵌套子命令创建命令行界面 (CLI) 的过程,并为开发人员和用户提供许多好处。

TreeBasedCli 的关键特性之一是其模块化结构,它允许您使用叶和分支命令轻松地组织和构建 CLI 的功能。 叶命令表示可以执行的特定操作,并作为具有自己的命令定义、输入解析器和异步处理程序的单独类来实现。 另一方面,分支命令表示一组子命令并且没有关联的操作。 这使您可以轻松创建具有多层嵌套的复杂 CLI。

TreeBasedCli 的另一个好处是它支持异步命令执行。 它还包括一个轻量级的依赖注入 (DI) 接口,允许您使用您喜欢的 DI 类型解析方法。

public class CreateCatCommand :
    LeafCommand<
        CreateCatCommand.Arguments,
        CreateCatCommand.Parser,
        CreateCatCommand.Handler>
{
    private const string NameLabel = "--name";

    public CreateCatCommand() : base(
        label: "create-cat",
        description: new[]
        {
            "Prints out a cat."
        },
        options: new[]
        {
            new CommandOption(
                label: NameLabel,
                description: new[]
                {
                    "Required. The name of the cat to print."
                }
            ),
        },
        DependencyInjectionService.Instance)
    { }

    public record Arguments(string CatName) : IParsedCommandArguments;

    public class Parser : ICommandArgumentParser<Arguments>
    {
        public IParseResult<Arguments> Parse(CommandArguments arguments)
        {
            string name = arguments.GetArgument(NameLabel).ExpectedAsSingleValue();

            var result = new Arguments(
                CatName: name
            );

            return new SuccessfulParseResult<Arguments>(result);
        }
    }

    public class Handler : ICommandHandler<Arguments>
    {
        private readonly IUserInterface userInterface;

        public Handler(IUserInterface userInterface)
        {
            this.userInterface = userInterface;
        }

        public Task HandleAsync(Arguments arguments, LeafCommand _)
        {
            this.userInterface.WriteLine($"I am a cat 😸 with the name {arguments.CatName}!");
            return Task.CompletedTask;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM