2017-03-29 7 views
4

次のように私はオプションを定義していますコマンドラインパーサー動詞のヘルプが機能していませんか?

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

しかし、私は「ヘルプのconfigure」で私のexeファイルを実行しようとした場合、それだけで全体のヘルプをプリントアウトし、 GetUsage(string)メソッドでは、デバッガに表示される「help」コマンドだけがあります。

これはバグですか、それとも何ですか?

+0

あなたが使用しているcmd argsライブラリなどのコンテキスト情報を少し追加するのを忘れたと思います。 – Tamas

+1

私は3タイトルの単語が実際の名前を見つけるのに役立つと思う:コマンドラインパーサー – eocron

+0

ありがとう。私はそれらのものを見逃した。この場合、これは間違いなく問題です。[ここ](https://github.com/gsscoder/commandline/issues/298)と[ここ](https://github.com/gsscoder/)で確認できます。コマンドライン/ issue/347)。 – Tamas

答えて

5

これはバグです。

あなたのプログラムと同じで、同じ(誤った)振る舞いをしていて、コマンドラインプロジェクト自体に切り替えましたが、同じ問題がありましたが、問題が見つかりました。

あなたのプロジェクトに組み込まれたコマンドラインパーサの「ソース」バージョンを使用している場合は、次のように、あなたはそれを修正すること(以下のコードは、クラス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; 
    } 

残念ながら、場合あなたはコマンドラインパーサーDLLに直接リンクしています。私はそれに対処する方法はないと思います。この場合、作成者のみが修正できます。

0

Console ToolKitを使用してコマンドライン操作を管理することを検討してください。これは、コンソール操作の困難な問題の大部分を扱っています。コンソールアプリケーションをはるかに速く書くことができます!

+0

[OPが使用しているライブラリ](https://www.nuget.org/packages/CommandLineParser)との違いは何ですか?これは質問への非常に間接的な答えであると思われ、むしろコメントであるべきです。 –

2

NuGetパッケージを使用している場合は、ここで簡単に回避できます。 argsにオプションを格納して、実際の動詞をHelpText.AutoBuildに転送できるようにします。また、HelpText.AutoBuildを検査するためにVerb Optionのインスタンスを用意する必要があります。

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 }; 
関連する問題