如何在使用 System.Commandline 库构建的应用中自定义帮助

可以自定义特定命令、选项或参数的帮助,还可以添加或替换全部帮助部分。

本文中的示例使用以下命令行应用程序:

此代码需要 using 指令:

using System.CommandLine;
var fileOption = new Option<FileInfo>(
    "--file",
    description: "The file to print out.",
    getDefaultValue: () => new FileInfo("scl.runtimeconfig.json"));
var lightModeOption = new Option<bool> (
    "--light-mode",
    description: "Determines whether the background color will be black or white");
var foregroundColorOption = new Option<ConsoleColor>(
    "--color",
    description: "Specifies the foreground color of console output",
    getDefaultValue: () => ConsoleColor.White);

var rootCommand = new RootCommand("Read a file")
{
    fileOption,
    lightModeOption,
    foregroundColorOption
};

rootCommand.SetHandler((file, lightMode, color) =>
    {
        Console.BackgroundColor = lightMode ? ConsoleColor.White: ConsoleColor.Black;
        Console.ForegroundColor = color;
        Console.WriteLine($"--file = {file?.FullName}");
        Console.WriteLine($"File contents:\n{file?.OpenText().ReadToEnd()}");
    },
    fileOption,
    lightModeOption,
    foregroundColorOption);

await rootCommand.InvokeAsync(args);

如果没有自定义,则生成以下帮助输出:

Description:
  Read a file

Usage:
  scl [options]

Options:
  --file <file>                                               The file to print out. [default: scl.runtimeconfig.json]
  --light-mode                                                Determines whether the background color will be black or
                                                              white
  --color                                                     Specifies the foreground color of console output
  <Black|Blue|Cyan|DarkBlue|DarkCyan|DarkGray|DarkGreen|Dark  [default: White]
  Magenta|DarkRed|DarkYellow|Gray|Green|Magenta|Red|White|Ye
  llow>
  --version                                                   Show version information
  -?, -h, --help                                              Show help and usage information

自定义单个选项或参数的帮助

重要

System.CommandLine 目前为预览版,本文档适用于版本 2.0 beta 4。 一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。

若要自定义选项的参数的名称,请使用选项的 ArgumentHelpName 属性。 借助 HelpBuilder.CustomizeSymbol,你可以自定义命令、选项或参数的帮助输出的若干部分,(Symbol 是所有三个类型的基类)。 利用 CustomizeSymbol,你可以指定:

  • 第一列文本。
  • 第二列文本。
  • 描述默认值的方式。

在示例应用中,--light-mode 可以得到充分说明,但对 --file--color 选项说明的更改将很有用。 对于 --file,可以将参数标识为 <FILEPATH> 而非 <file>。 对于 --color 选项,可以缩短第一列中可用颜色的列表,可以在第二列中添加一条警告,指示某些颜色不适用于某些背景。

若要进行这些更改,请删除前面代码中显示的 await rootCommand.InvokeAsync(args); 行,并在其位置添加以下代码:

fileOption.ArgumentHelpName = "FILEPATH";

var parser = new CommandLineBuilder(rootCommand)
        .UseDefaults()
        .UseHelp(ctx =>
        {
            ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption,
                firstColumnText: "--color <Black, White, Red, or Yellow>",
                secondColumnText: "Specifies the foreground color. " +
                    "Choose a color that provides enough contrast " +
                    "with the background color. " + 
                    "For example, a yellow foreground can't be read " +
                    "against a light mode background.");
        })
        .Build();

parser.Invoke(args);

更新的代码需要其他 using 指令:

using System.CommandLine.Builder;
using System.CommandLine.Help;
using System.CommandLine.Parsing;

应用现在生成以下帮助输出:

Description:
  Read a file

Usage:
  scl [options]

Options:
  --file <FILEPATH>                       The file to print out. [default: CustomHelp.runtimeconfig.json]
  --light-mode                            Determines whether the background color will be black or white
  --color <Black, White, Red, or Yellow>  Specifies the foreground color. Choose a color that provides enough contrast
                                          with the background color. For example, a yellow foreground can't be read
                                          against a light mode background.
  --version                               Show version information
  -?, -h, --help                          Show help and usage information

此输出显示 firstColumnTextsecondColumnText 参数支持在其列中换行。

添加或替换帮助部分

可以添加或替换帮助输出的整个部分。 例如,假设你想要通过使用 Spectre.Console NuGet 包将一些 ASCII 字符画添加到“描述”部分。

通过在传递给 UseHelp 方法的 lambda 中添加对 HelpBuilder.CustomizeLayout 的调用来更改布局:

fileOption.ArgumentHelpName = "FILEPATH";

var parser = new CommandLineBuilder(rootCommand)
        .UseDefaults()
        .UseHelp(ctx =>
        {
            ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption,
                firstColumnText: "--color <Black, White, Red, or Yellow>",
                secondColumnText: "Specifies the foreground color. " +
                    "Choose a color that provides enough contrast " +
                    "with the background color. " +
                    "For example, a yellow foreground can't be read " +
                    "against a light mode background.");
            ctx.HelpBuilder.CustomizeLayout(
                _ =>
                    HelpBuilder.Default
                        .GetLayout()
                        .Skip(1) // Skip the default command description section.
                        .Prepend(
                            _ => Spectre.Console.AnsiConsole.Write(
                                new FigletText(rootCommand.Description!))
                ));
        })
        .Build();

await parser.InvokeAsync(args);

前面的代码需要其他 using 指令:

using Spectre.Console;

借助 System.CommandLine.Help.HelpBuilder.Default 类,可重用现有帮助格式设置功能的片段,并将其组合到自定义帮助中。

帮助输出现在如下所示:

  ____                       _                __   _   _
 |  _ \    ___    __ _    __| |     __ _     / _| (_) | |   ___
 | |_) |  / _ \  / _` |  / _` |    / _` |   | |_  | | | |  / _ \
 |  _ <  |  __/ | (_| | | (_| |   | (_| |   |  _| | | | | |  __/
 |_| \_\  \___|  \__,_|  \__,_|    \__,_|   |_|   |_| |_|  \___|


Usage:
  scl [options]

Options:
  --file <FILEPATH>                       The file to print out. [default: CustomHelp.runtimeconfig.json]
  --light-mode                            Determines whether the background color will be black or white
  --color <Black, White, Red, or Yellow>  Specifies the foreground color. Choose a color that provides enough contrast
                                          with the background color. For example, a yellow foreground can't be read
                                          against a light mode background.
  --version                               Show version information
  -?, -h, --help                          Show help and usage information

如果只想使用字符串作为替换部分文本,而不是使用 Spectre.Console 对其进行格式设置,请将前面示例中的 Prepend 代码替换为以下代码:

.Prepend(
    _ => _.Output.WriteLine("**New command description section**")

请参阅

System.CommandLine 概述