簡體   English   中英

如何使用NDesk.Options強制執行必需的命令行選項?

[英]How to enforce required command-line options with NDesk.Options?

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

我在文檔中看到:

具有必需值(在選項名稱后附加'=')或可選值(在選項名稱后附加':')的選項。

但是,當我在選項名稱的末尾添加=時,行為沒有區別。 理想情況下,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);
    }
}

問題在於文檔不像顯然需要的那樣清晰。 :-(

具體來說,按照:

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

可以稍微擴展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和私有bool optionSet。

第四,在創建目標值時將其傳遞給Option。 訂閱PropertyChanged事件。 如果發件人不為null,則在其中將“ optionSet”設置為true。

如果目標值不為null且o​​ptionSet為false,則將Validate()方法添加到Option類,該方法將引發異常。

最后,向OptionContext添加Validate()方法,該方法將遍歷所有選項並調用它們各自的Validate()方法。 在Parse()方法的最后調用它。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM