2010-08-06 30 views
34

我只是寫了一個控制檯實用程序,並決定使用NDesk.Options進行命令行解析。我的問題是,我如何執行必需的命令行選項?如何使用NDesk.Options強制執行必需的命令行選項?

我在docs看出:具有所需值

選項(附加「=」與選項名稱)或可選值(追加「:」在選項名稱)。

但是,當我在選項名稱末尾加上=時,行爲沒有區別。理想情況下,Parse方法會拋出異常。

有什麼我需要做的嗎?

這裏是我的測試代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     bool show_help = false; 
     string someoption = null; 

     var p = new OptionSet() { 
      { "someoption=", "Some String Option", v => someoption = v}, 
      { "h|help", "show this message and exit", v => show_help = v != null } 
     }; 

     List<string> extra; 
     try 
     { 
      extra = p.Parse(args); 
     } 
     catch (OptionException e) 
     { 
      System.Console.Write("myconsole: "); 
      System.Console.WriteLine(e.Message); 
      System.Console.WriteLine("Try `myconsole --help' for more information."); 
      return; 
     } 

     if (show_help) 
     { 
      ShowHelp(p); 
      return; 
     } 

     System.Console.WriteLine("=================="); 
     System.Console.WriteLine(someoption); 
    } 

    static void ShowHelp(OptionSet p) 
    { 
     System.Console.WriteLine("Usage: myconsole [OPTIONS]"); 
     System.Console.WriteLine(); 
     System.Console.WriteLine("Options:"); 
     p.WriteOptionDescriptions(System.Console.Out); 
    } 
} 
+1

我有同樣的問題。接縫NDesk.Options不會拋出異常。 – 2010-09-08 15:53:50

回答

39

的問題是,文件不明確的,因爲它顯然必須這樣做。 :-(

具體來說,按照:

http://www.ndesk.org/doc/ndesk-options/NDesk.Options/OptionValueType.html#F:NDesk.Options.OptionValueType.Required

選項規範並不適用於OptionSet作爲一個整體中的=,而只是針對特定選項

這一點的重要性真的只有在兩種情況下相關的,所以首先讓我們考慮OptionSet解析器:

string a = null; 
string b = null; 
var options = new OptionSet { 
    { "a=", v => a = v }, 
    { "b=", v => b = v }, 
}; 

情況1重要的是,OptionSet.Parse()以單向,只進方式工作,並且不是查看選項值以確定它們是否應該是值。因此,可以考慮:

options.Parse(new[]{"-a", "-b"}); 

這樣做的結果將是a具有價值"-b",並bnull。由於-a的處理程序需要 a值,因此始終爲會得到以下值(除非該值已「編碼」爲原始選項,例如-a=value)。

第二個地方,這是很重要的是當值,需要選擇是最後的選擇,並沒有存在的價值了吧:

options.Parse(new[]{"-a"}); 

這將引發OptionException,作爲處理對於-a需要一個值,並且不存在任何值。

因此,如果你有自己需要(而不是需要值的選項)選項,則需要手動檢查此:

string dir = null; 
new OptionSet { 
    { "o=", v => dir = v }, 
}.Parse (args); 

if (dir == null) 
    throw new InvalidOperationException ("Missing required option -o=DIR"); 
2

一個可以擴展NDesk.Options一點位來添加此功能。

首先,創建一個類SetupOption將執行INotifyPropertyChanged:

class SetupOption<T> : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    private T _value; 

    public T Value 
    { 
     get 
     { 
      return _value; 
     } 
     set 
     { 
      _value = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(_value, new PropertyChangedEventArgs("Value")); 
      } 
     } 
    } 
} 

二,添加一個超載ActionOption這需要INotifyPropertyChanged的實例作爲參數(稱之爲targetValue)。

三,修改Option類以添加私有的INotifyPropertyChanged targetValue和private bool optionSet。

四,創建時將targetValue傳遞給Option。訂閱PropertyChanged事件。其中,如果發件人不爲空,請將「optionSet」設置爲true。

將Validate()方法添加到Option類,如果targetValue不爲null且o​​ptionSet爲false,則會引發異常。

最後,將一個Validate()方法添加到OptionContext中,該方法將遍歷所有選項並調用其各自的Validate()方法。在Parse()方法的最後調用它。

這是修改後的代碼的zip:http://www.davidair.com/misc/options.zip

相關問題