【问题标题】:Translate NDesk.Options.OptionSet construction to PowerShell将 NDesk.Options.OptionSet 构造转换为 PowerShell
【发布时间】:2011-11-05 03:26:46
【问题描述】:

下面是典型的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&lt;string&gt;,但我找不到如何转换为string[]

那么,我的问题是如何在没有这些讨厌的异常的情况下将原始 C# 代码转换为 Powershell?

谢谢。

编辑

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

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

【问题讨论】:

  • 你能说出你想要达到的目标吗?或者甚至可能就如何在 PowerShell 中实现这一点提出一个单独的问题?你问如何使用不应该在 PowerShell for PowerShell 中使用的工具。
  • 尝试将第三个参数明确地转换为您需要的类型(Action?)。此外,在 PowerShell(v2,希望 v3 会有所不同)中使用泛型方法并不容易。看看这篇文章(希望,这会有所帮助):leeholmes.com/blog/2007/06/19/…
  • 我该如何转换为 Action

标签: powershell


【解决方案1】:

PowerShell 有自己的函数和 cmdlet 的本机参数/参数解析器/绑定器。你不能用 NDesk.Options 覆盖它,所以你在风中小便,恐怕我的好人。在你说“天哪,太糟糕了”之前,你应该考虑一下 powershell 的更大目标。通过内置参数绑定器,函数/命令调用样式是不变的:不用怀疑它是斜线还是连字符、双斜线、等号、冒号等。这与 cmdlet 和函数在命名时使用熟悉的动词-名词表示法的原因相同.与其猜测如何调用事物并弄错,您实际上可以着手进行更有用的活动,即发现您可以做什么。

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

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

【讨论】:

  • 这个问题有两个目标 - 提高我的 PS 技能并能够使用熟悉的(而且很棒的)库解析命令行参数。但我没有锁定 NDesk.Options - stackoverflow.com/questions/8004967/…
  • 我想你错过了我的观点 - powershell 不提供对原始参数的访问,因此你将无法可靠地使用任何其他库。不存在 argc/argv 的等价物,这是一件好事。我并不是说 NDesk.Options 不好(确实如此),但它适用于原始控制台应用程序。
  • 好的,我的另一篇帖子已经回答了,所以我知道如何在PowerShell中处理命令行参数。让我们忘记命令行解析,谈谈从 PowerShell 调用某些 .NET 代码。无论命令行参数如何,我都想让代码正常工作。
  • 你想在你能走路之前先跑。阅读那本电子书。强制转换很简单: $strarray = [string[]] $arr -- 作为一般指南,powershell 的类型强制比 c# 宽得多。
  • 我必须承认我尝试过投射但没有成功。但是,我已经知道为什么了。我做了一件愚蠢的事情,用 ildasm 反编译 NDesk.Options,将 mscorlib 和其他的版本更改为 2.0.0.0,然后用 ilasm 重新编译以使其与 PowerShell ScriptEngine 一起工作,而不是简单地重新定位后者以针对 .NET 4 工作。我的 hack 在运行时惨遭失败,因为 mscorlib 2.0.0.0 没有定义 Func&lt;T1,T2&gt;(尽管我预计在编译时会失败)。无论如何,现在投射到string[] 工作正常,但是MethodCountCouldNotFindBest 错误呢?
猜你喜欢
  • 2015-09-17
  • 2021-07-14
  • 2016-12-24
  • 1970-01-01
  • 2019-04-25
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
相关资源
最近更新 更多