将NDesk.Options.OptionSet构造转换为PowerShell

时间:2011-11-03 21:16:29

标签: powershell

以下是典型的OptionSet构造代码:

var p = new OptionSet {
  { "h|help", "Show this help", v => { isHelp = (v != null); } },
};

var extra = p.Parse(args);

相同代码的我的Powershell版本是:

$p = New-Object NDesk.Options.OptionSet
$p.Add("h|help", "Show this help", { param([string]$v) $global:isHelp = $true })
$extra = $p.Parse($args)

不幸的是,它有两个问题。当我执行第二行时,我得到了这个:

Multiple ambiguous overloads found for "Add" and the argument count: "3".
At C:\Work\hg\utils\HgTagPromotedBuild.ps1:62 char:7
+ $p.Add <<<< ("h|help", "Show this help message", { param([string]$v) $global:isHelp =
 $true })
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

然后执行下一行导致:

Cannot convert argument "0", with value: "System.Object[]", for "Parse" to type "System
.Collections.Generic.IEnumerable`1[System.String]": "Cannot convert the "System.Object[
]" value of type "System.Object[]" to type "System.Collections.Generic.IEnumerable`1[Sy
stem.String]"."
At C:\Work\hg\utils\HgTagPromotedBuild.ps1:63 char:18
+ $extra = $p.Parse <<<< ($args)
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

OptionSet声明的相关部分是:

public OptionSet Add(Option option);
public OptionSet Add(string prototype, OptionAction<string, string> action);
public OptionSet Add<TKey, TValue>(string prototype, OptionAction<TKey, TValue> action);
public OptionSet Add<T>(string prototype, Action<T> action);
public OptionSet Add(string prototype, Action<string> action);
public OptionSet Add<TKey, TValue>(string prototype, string description, OptionAction<TKey, TValue> action);
public OptionSet Add(string prototype, string description, OptionAction<string, string> action);
public OptionSet Add<T>(string prototype, string description, Action<T> action);
public OptionSet Add(string prototype, string description, Action<string> action);

我根本不明白第一个错误中发生了什么。

第二个很清楚 - 显然$args被输入为object[],而OptionSet.Parse则需要IEnumerable<string>,但我无法找到如何投放到string[]

所以,我的问题是如何在没有这些令人讨厌的异常的情况下将原始C#代码翻译为Powershell?

感谢。

修改

感谢所有让我明白PowerShell有一个明确定义的方法来处理命令行参数的人。我已经承认了这一事实,甚至创建了一个专门的SO问题 - Is there a decent command line parser for powershell?,我已经标记为已回答。再次感谢所有人。

现在,我仍然有兴趣知道如何尽可能从PowerShell调用特定的.NET代码。没有与命令行参数解析的连接。只是纯粹的知识追求。

1 个答案:

答案 0 :(得分:4)

PowerShell有自己的本机参数/参数解析器/绑定器,用于函数和cmdlet。你不能用NDesk.Options覆盖它,所以你在风中撒尿我害怕我的好人。在你说“jeez,那糟透了”之前,你应该考虑一下PowerShell的更大目标。通过使用一个带烘焙的参数绑定器,函数/命令调用样式是不变的:不知道它是斜杠还是连字符,双精度,等号,冒号等。这就是为什么cmdlet和函数在命名中使用熟悉的动词 - 名词表示法的原因。您可以实际上了解发现您可以做的事情的更有用的活动,而不是猜测如何调用事物并弄错。

您想从更广阔的视角实现目标?发布所需的参数绑定语义,我将向您展示如何在powershell函数中声明它。

更新:如果您想了解有关powershell的更多信息,请阅读我的好朋友Keith Hill的免费电子书:有效的Windows PowerShell,PDF格式免费提供:http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/