Как применить необходимые параметры командной строки с помощью NDesk.Варианты?
Я просто писал консольную утилиту и решил использовать NDesk.Параметры синтаксического анализа командной строки. Мой вопрос в том, как я могу обеспечить требуемые параметры командной строки?
Я вижу 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);
}
}
2 ответов
проблема в том, что документация не так ясна, как это, по-видимому, должно быть. :-(
в частности, согласно:
на =
в спецификации опции не применяется к 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"
и b
is null
. Так как обработчик для -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.Опции немного добавить эту функциональность.
сначала создайте класс 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, чтобы добавить private INotifyPropertyChanged targetValue и private bool optionSet.
в-четвертых, пройти targetValue к опции при ее создании. Подписаться на событие PropertyChanged. В нем установите для параметра "optionSet" значение true, если отправитель не равен null.
добавьте метод Validate () в класс Option, который выдаст исключение, если targetValue не равно null, а optionSet-false.
наконец, добавьте метод Validate() в OptionContext, который будет перебирать все параметры и вызывать их соответствующие методы Validate (). Назовите это в самом конце разбора() метод.
вот zip измененного кода:http://www.davidair.com/misc/options.zip