管道参数与其他参数的特定组合时“无法解析参数集”

如何解决管道参数与其他参数的特定组合时“无法解析参数集”

我编写了一个使用四个参数和四个参数集的函数。第一个参数 $Path 未分配给一个集合,因此属于所有集合。它也是强制性的,并且是唯一可以从管道中传递的参数。但是,当我在管道末尾调用函数时,使用其他三个参数的某些组合(所有这些都属于四组的某种组合)执行此操作时,我收到一个错误,表明该组不明确。>

这是我的功能

function Foo-Bar {
    [CmdletBinding(DefaultParameterSetName = 'A')]

    param (
        [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $Path,[Parameter(ParameterSetName = 'A')]
        [Parameter(ParameterSetName = 'A-Secure')]
        [Switch] $OutputToConsole,[Parameter(Mandatory = $true,ParameterSetName = 'B')]
        [Parameter(Mandatory = $true,ParameterSetName = 'B-Secure')]
        [int] $OutputMode,ParameterSetName = 'A-Secure')]
        [Parameter(Mandatory = $true,ParameterSetName = 'B-Secure')]
        [Switch] $Login
    )

    $PSCmdlet.ParameterSetName
}

所有可能的参数组合如下:

PS C:\> Foo-Bar -Path "C:\Test.jpg"
A
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputToConsole
A
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputToConsole -Login
A-Secure
PS C:\> Foo-Bar -Path "C:\Test.jpg" -Login
A-Secure
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputMode 1
B
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputMode 1 -Login
B-Secure

单独通过管道传递 $Path 或使用这些其他参数组合工作正常:

PS C:\> "C:\Test.jpg" | Foo-Bar
A
PS C:\> "C:\Test.jpg" | Foo-Bar -OutputToConsole
A
PS C:\> "C:\Test.jpg" | Foo-Bar -OutputToConsole -Login
A-Secure
PS C:\> "C:\Test.jpg" | Foo-Bar -OutputMode 1 -Login
B-Secure

但这两种组合会导致错误

PS C:\> "C:\Test.jpg" | Foo-Bar -Login
Foo-Bar: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
PS C:\> "C:\Test.jpg" | Foo-Bar -OutputMode 1
Foo-Bar: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

似乎这些结果之间最大的区别是 $OutputToConsole,这是其两个集合中唯一可选的参数。似乎管道一个强制性参数会导致它本身成为强制性参数。另一方面,最令人困惑的结果涉及 $OutputMode,因为它的两个集合都使用了完全必需参数的不同组合。当同时使用 $Path$OutputMode 时会出现集合 B,仅此而已。那么,"C:\Test.jpg" | Foo-Bar -OutputMode 1 是如何被认为是模棱两可的?

我将非常感谢任何可以为我阐明这一点的人。

解决方法

不要问我为什么
(以下解决方法返回相同的语法:Foo-Bar -?
就我个人而言,我发现参数集安静混乱且冗长(因此我为 Hierarchical Parameter Scripting #13746 做了这个目的)

无论如何,作为一种可能的解决方法;将 Path 参数放入所有参数集中:

function Foo-Bar {
    [CmdletBinding(DefaultParameterSetName = 'A')]

    param (
        [Parameter(Mandatory = $true,ValueFromPipeline = $true,ParameterSetName = 'A')]
        [Parameter(Mandatory = $true,ParameterSetName = 'B')]
        [Parameter(Mandatory = $true,ParameterSetName = 'A-Secure')]
        [Parameter(Mandatory = $true,ParameterSetName = 'B-Secure')]
        [ValidateNotNullOrEmpty()]
        [string[]] $Path,[Parameter(ParameterSetName = 'A')]
        [Parameter(ParameterSetName = 'A-Secure')]
        [Switch] $OutputToConsole,[Parameter(Mandatory = $true,ParameterSetName = 'B-Secure')]
        [int] $OutputMode,ParameterSetName = 'B-Secure')]
        [Switch] $Login
    )

    $PSCmdlet.ParameterSetName
}

"C:\Test.jpg" | Foo-Bar -Login
A-Secure
,

参数集必须至少包含一个唯一参数

声明参数集要创建参数集,您必须指定 每个参数的 Parameter 属性的 ParameterSetName 关键字 参数集中的参数。对于属于多个的参数 参数集,为每个参数集添加一个 Parameter 属性。

Parameter 属性使您能够定义参数 每个参数集不同。例如,您可以定义一个 参数在一组中是必需的,在另一组中是可选的。 不过, 每个参数集必须至少包含一个唯一参数。

没有指定参数集名称的参数属于 所有参数集。

来源:Declaring Parameters Sets


更新 - 仔细观察

Foo-Bar

ParameterSetName Parameters
---------------- ----------
A                -Path <string[]> [-OutputToConsole] [<CommonParameters>]
A-Secure         -Path <string[]> -Login [-OutputToConsole] [<CommonParameters>]
B-Secure         -Path <string[]> -OutputMode <int> -Login [<CommonParameters>]
B                -Path <string[]> -OutputMode <int> [<CommonParameters>]

进入时

C:\Test.jpg" | Foo-Bar -Login

PoSH 无法确定它应该与 A-Secure 还是 B-Secure 一起使用。在 B-Secure 中您有一个额外的强制性参数 (-OutputMode) 并不重要。从它收到的信息来看,它无法判断要使用哪个,因为有多个匹配选项。这种组合不是唯一的。

"C:\Test.jpg" | Foo-Bar -OutputMode 1

这里也一样,只有输出模式。它收到了一个 Path 和一个 OutputMode 参数,但这与 B-Secure 和 B 都匹配。不是唯一的。

Microsoft Measure-Lines 示例

ParameterSetName Parameters
---------------- ----------
Path             [-Path] <string[]> [-Lines] [-Words] [-Characters] [-Recurse] [<CommonParameters>]
PathAll          [-Path] <string[]> -All [-Recurse] [<CommonParameters>]
LiteralPath      -LiteralPath <string> [-Lines] [-Words] [-Characters] [<CommonParameters>]
LiteralPathAll   -LiteralPath <string> -All [<CommonParameters>]

乍一看,Measure-Lines 示例似乎很相似,但不同之处在于前 2 个参数集采用 Path 参数,而后 2 个参数集采用 LiteralPath 参数。这使得它们足够独特,以便 Powershell 知道在使用 -All 开关时要使用的参数集。当与 -Path 参数一起使用时,它与 PathAll 集一起使用,当提供 -LiteralPath 时使用 LiteralPathAll。

,

遵循iRons answer,我认为您还可以在这里大幅减少参数集的数量:

function Foo-Bar {
    [CmdletBinding(DefaultParameterSetName = 'None')]

    param (
        [ValidateNotNullOrEmpty()]
        [string[]] $Path,[Parameter(ParameterSetName = 'A-Secure')]
        [Switch] $OutputToConsole,ParameterSetName = 'B-Secure')]
        [Switch] $Login
    )

    $PSCmdlet.ParameterSetName
}

Foo-Bar -Login                                            # --> chosen param set: 'A-Secure' because that the first one mentioned on the Login parameter
Foo-Bar -Path 'D:\Test\blah.txt'                          # --> chosen param set: 'None' because that is the DefaultParameterSetName
Foo-Bar -Path 'D:\Test\blah.txt' -OutputMode 5            # --> prompts you to also supply parameter 'Login'
Foo-Bar -Path 'D:\Test\blah.txt' -OutputToConsole -Login  # --> parameter -OutputMode now not available; chosen param set: 'B-Secure'
Foo-Bar -Path 'D:\Test\blah.txt' -OutputMode 5 -Login     # --> parameter -OutputToConsole now not available; chosen param set: 'A-Secure'

# parameters '-Path' and '-Login' are always available for both 'A-Secure' and 'B-Secure'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?