2011-11-03 94 views
0

下面是一个典型OptionSet建设代码:翻译NDesk.Options.OptionSet建设的PowerShell

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

你能告诉你想达到什么?或者,甚至可以问一个关于如何在PowerShell中实现这个问题的单独问题?你问如何使用PowerShell *中不应该使用的工具。 –

+0

我编辑了我的文章。 – mark

+0

尝试将第三个参数转换为明确需要的类型(动作?)。另外,在PowerShell(v2,希望v3会有所不同)不太容易使用泛型方法。看看这篇文章(希望,这有助于):http://www.leeholmes.com/blog/2007/06/19/invoking-generic-methods-on-non-generic-classes-in-powershell/ –

回答

4

PowerShell具有自己的参数/参数解析器/活页夹,用于函数和cmdlet。你不能用NDesk.Options覆盖这个,所以你在这里吹风,我怕我的好人。在你说“jeez,这很糟糕”之前,你应该考虑一下关于powershell的更大目标。通过使用烘焙参数联编程序,函数/命令调用样式是不变的:不会怀疑它是斜线还是连字符,双精度,等号,冒号等。这与cmdlet和函数在命名中使用熟悉的动词 - 名词符号的原因相同。与其猜测如何引用事物并使其错误,你实际上可以开始发现你能做的更有用的活动。

你想从更广阔的角度实现什么?发布所需的参数绑定语义,我会告诉你如何在PowerShell函数中声明它。

更新:如果您想了解更多关于PowerShell的,必须通过我的好朋友基思·希尔的免费电子书读:有效的Windows PowerShell,提供免费的PDF:http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/

+0

这个问题有两个目标 - 提高我的PS技能,并能够使用熟悉的(和伟大的)库来解析命令行参数。但我没有锁定在NDesk.Options - http://stackoverflow.com/questions/8004967/is-there-a-decent-command-line-parser-for-powershell – mark

+0

我想你错过了我的观点 - powershell不提供对原始参数的访问,因此您将无法可靠地使用任何其他库。没有相当于argc/argv,这是一件好事。我不是说NDesk.Options不是很好(它是),但它是用于原始控制台应用程序。 – x0n

+0

好吧,我的另一篇文章已经得到了回答,所以我知道如何处理PowerShell中的命令行参数。让我们忘记命令行解析并讨论从PowerShell调用某些.NET代码。我想使代码工作,不管命令行参数的东西。 – mark