34

मैं सिर्फ एक कंसोल उपयोगिता लिख ​​रहा था और कमांड लाइन पार्सिंग के लिए NDesk.Options का उपयोग करने का निर्णय लिया। मेरा सवाल है, मैं आवश्यक कमांड लाइन विकल्पों को कैसे लागू करूं?NDesk.Options के साथ आवश्यक कमांड लाइन विकल्पों को कैसे लागू करें?

मैं docs में देखते हैं कि: एक आवश्यक मूल्य के साथ

विकल्प या एक वैकल्पिक मूल्य (विकल्प नाम को संलग्न '=') (संलग्न ':' विकल्प नाम के लिए)।

हालांकि, जब मैं विकल्प नाम के अंत में = डालता हूं तो व्यवहार में कोई अंतर नहीं होता है। आदर्श रूप से पार्स विधि एक अपवाद फेंक देगा।

क्या मुझे कुछ और करने की ज़रूरत है?

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 अपवाद फेंक नहीं होगा। –

उत्तर

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=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 कहते हैं)।

तीसरा, निजी INOTifyPropertyChanged targetValue और निजी बूल विकल्प सेट जोड़ने के लिए विकल्प वर्ग को संशोधित करें।

चौथा, इसे बनाते समय लक्ष्य के लक्ष्य को पास करें। PropertyChanged घटना की सदस्यता लें। इसमें, अगर प्रेषक शून्य नहीं है तो "विकल्पसेट" को सत्य पर सेट करें।

विकल्प वर्ग में एक वैध() विधि जोड़ें जो लक्ष्य अपवाद शून्य नहीं है और विकल्पसेट गलत है।

अंत में, OptionContext में एक मान्य() विधि जोड़ें जो सभी विकल्पों पर लूप होगा और उनके संबंधित मान्य() विधियों को कॉल करेगी। पार्स() विधि के बहुत अंत में इसे कॉल करें। http://www.davidair.com/misc/options.zip

संबंधित मुद्दे