以下是典型的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代码。没有与命令行参数解析的连接。只是纯粹的知识追求。
答案 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/