命令行解析器动词帮助不起作用?
Command Line Parser verb help not working?
我定义的选项如下:
public class ArgumentsHeader
{
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; }
[HelpVerbOption]
public string GetUsage(string s)
{
return HelpText.AutoBuild(this, s);//always just 'help' or null showing up here.
}
}
public class ServerConfigurationArguments : ArgumentsBase
{
[Option('f', "filename", HelpText = "Path to JSON configuration file", DefaultValue = "config.json", Required = true)]
public string PathToConfig { get; set; }
}
然后像这样解析它们:
string invokedVerb = null;
object invokedVerbInstance = null;
var parser = new Parser(x =>
{
x.MutuallyExclusive = true;
});
var options = new ArgumentsHeader();
if (!parser.ParseArguments(args, options,
(verb, subOptions) =>
{
// if parsing succeeds the verb name and correct instance
// will be passed to onVerbCommand delegate (string,object)
invokedVerb = verb;
invokedVerbInstance = subOptions;
}))
{
Exit(ExitStatus.InvalidArguments);
}
但是如果我尝试 运行 我的 exe 与 'help configure' 它只会打印出整个帮助,并且在 GetUsage(string) 方法中只有 'help' 命令出现在调试器。
是bug还是什么?
这是一个错误。
我检查了一个与您的程序类似的程序并且有相同的(错误)行为,然后切换到命令行项目本身,有相同的但我想我发现了问题。
如果您使用的是项目中嵌入的 "source" 版本的命令行解析器,您可以按如下方式修复它(以下代码来自 class commandLine.Parser):
private bool TryParseHelpVerb(string[] args, object options, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, OptionMap optionMap)
{
var helpWriter = _settings.HelpWriter;
if (helpInfo != null && helpWriter != null)
{
if (string.Compare(args[0], helpInfo.Right.LongName, GetStringComparison(_settings)) == 0)
{
// User explicitly requested help
// +++ FIX
// var verb = args.FirstOrDefault(); // This looks wrong as the first element is always the help command itself
var verb = args.Length == 1 ? null : args[1]; // Skip the help command and use next argument as verb
// --- FIX
if (verb != null)
{
var verbOption = optionMap[verb];
if (verbOption != null)
{
if (verbOption.GetValue(options) == null)
{
// We need to create an instance also to render help
verbOption.CreateInstance(options);
}
}
}
DisplayHelpVerbText(options, helpInfo, verb);
return true;
}
}
return false;
}
不幸的是,如果您 link 直接访问命令行解析器 DLL,我认为没有任何解决方法。这种情况只能作者自己解决了...
如果您使用的是 NuGet 包,这里有一个快速解决方法。使用选项存储参数,以便您可以将实际动词转发给 HelpText.AutoBuild。此外,您还需要有一个动词选项实例供 HelpText.AutoBuild 检查。
public class ArgumentsHeader
{
public string[] args { get; set; } = new string[0];
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; } = new ServerConfigurationArguments();
[HelpVerbOption]
public string GetUsage(string verb)
{
if (verb?.ToLower() == "help" && args.Length > 1)
{
verb = args[1];
}
return HelpText.AutoBuild(this, verb);
}
}
然后用参数创建选项。
var options = new ArgumentsHeader { args = args };
您也可以传递 args 省略数组的第一项(这是可执行文件的名称)。
例如 (VB.NET):
Sub Main()
Dim args = Environment.GetCommandLineArgs().Skip(1)
Dim result = CommandLine.Parser.Default.ParseArguments(Of InstallOptions, UpdateOptions)(args)
...
我定义的选项如下:
public class ArgumentsHeader
{
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; }
[HelpVerbOption]
public string GetUsage(string s)
{
return HelpText.AutoBuild(this, s);//always just 'help' or null showing up here.
}
}
public class ServerConfigurationArguments : ArgumentsBase
{
[Option('f', "filename", HelpText = "Path to JSON configuration file", DefaultValue = "config.json", Required = true)]
public string PathToConfig { get; set; }
}
然后像这样解析它们:
string invokedVerb = null;
object invokedVerbInstance = null;
var parser = new Parser(x =>
{
x.MutuallyExclusive = true;
});
var options = new ArgumentsHeader();
if (!parser.ParseArguments(args, options,
(verb, subOptions) =>
{
// if parsing succeeds the verb name and correct instance
// will be passed to onVerbCommand delegate (string,object)
invokedVerb = verb;
invokedVerbInstance = subOptions;
}))
{
Exit(ExitStatus.InvalidArguments);
}
但是如果我尝试 运行 我的 exe 与 'help configure' 它只会打印出整个帮助,并且在 GetUsage(string) 方法中只有 'help' 命令出现在调试器。
是bug还是什么?
这是一个错误。
我检查了一个与您的程序类似的程序并且有相同的(错误)行为,然后切换到命令行项目本身,有相同的但我想我发现了问题。
如果您使用的是项目中嵌入的 "source" 版本的命令行解析器,您可以按如下方式修复它(以下代码来自 class commandLine.Parser):
private bool TryParseHelpVerb(string[] args, object options, Pair<MethodInfo, HelpVerbOptionAttribute> helpInfo, OptionMap optionMap)
{
var helpWriter = _settings.HelpWriter;
if (helpInfo != null && helpWriter != null)
{
if (string.Compare(args[0], helpInfo.Right.LongName, GetStringComparison(_settings)) == 0)
{
// User explicitly requested help
// +++ FIX
// var verb = args.FirstOrDefault(); // This looks wrong as the first element is always the help command itself
var verb = args.Length == 1 ? null : args[1]; // Skip the help command and use next argument as verb
// --- FIX
if (verb != null)
{
var verbOption = optionMap[verb];
if (verbOption != null)
{
if (verbOption.GetValue(options) == null)
{
// We need to create an instance also to render help
verbOption.CreateInstance(options);
}
}
}
DisplayHelpVerbText(options, helpInfo, verb);
return true;
}
}
return false;
}
不幸的是,如果您 link 直接访问命令行解析器 DLL,我认为没有任何解决方法。这种情况只能作者自己解决了...
如果您使用的是 NuGet 包,这里有一个快速解决方法。使用选项存储参数,以便您可以将实际动词转发给 HelpText.AutoBuild。此外,您还需要有一个动词选项实例供 HelpText.AutoBuild 检查。
public class ArgumentsHeader
{
public string[] args { get; set; } = new string[0];
[VerbOption("configure", HelpText = "Sets configuration on server.")]
public ServerConfigurationArguments ServerConfigurationArguments { get; set; } = new ServerConfigurationArguments();
[HelpVerbOption]
public string GetUsage(string verb)
{
if (verb?.ToLower() == "help" && args.Length > 1)
{
verb = args[1];
}
return HelpText.AutoBuild(this, verb);
}
}
然后用参数创建选项。
var options = new ArgumentsHeader { args = args };
您也可以传递 args 省略数组的第一项(这是可执行文件的名称)。 例如 (VB.NET):
Sub Main()
Dim args = Environment.GetCommandLineArgs().Skip(1)
Dim result = CommandLine.Parser.Default.ParseArguments(Of InstallOptions, UpdateOptions)(args)
...