powershell-core - 从自定义参数完成器/动态参数访问当前管道项
问题描述
我正在玩弄 cmdlet 的自定义参数完成器。为了学习如何编写它们,我制作了一个示例 cmdlet,其中一个是可取的;cmdlet 调用给定对象的方法,因此您需要发现它们可用的方法。当我最初开始时,我想因为内置 cmdletSelect-Object
很容易为自动完成提供对象属性名称,所以它很容易复制,但要使用方法名称。但是,自定义 cmdlet 似乎无法访问管道内容,所以我的想法落空了。
我觉得自然而然的另一件事是动态ValidateSet
地将输入限制为有效方法。长话短说,它也遇到了同样的问题。
这是我迄今为止尝试过的完整代码:
function Invoke-ObjectMethod {
[CmdletBinding()]
param(
# Method to call.
[Alias('Name', 'MethodName')]
# [ArgumentCompleter({
# [OutputType([System.Management.Automation.CompletionResult])]
# param(
# [string] $CommandName,
# [string] $ParameterName,
# [string] $WordToComplete,
# [System.Management.Automation.Language.CommandAst] $CommandAst,
# [System.Collections.IDictionary] $FakeBoundParameters
# )
# $_, $PSBoundParameters | Out-String | Out-Host
# if(!$FakeBoundParameters.ContainsKey('InputObject') -or $ParameterName -ne 'Method') {
# return
# }
# $static = $FakeBoundParameters.Static
# $FakeBoundParameters.InputObject | Get-Member "$WordToComplete*" -MemberType Method -Static:$static | ForEach-Object {
# $defs = $_ | Select-Object -ExpandProperty Definition | ForEach-Object { $_ -split '), ', 0, 'SimpleMatch' } | Join-String -Separator ")`n"
# New-Object -Type System.Management.Automation.CompletionResult -ArgumentList $_.Name, $_.Name, ParameterValue, $defs
# }
# })]
[Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName)]
[string]$Method,
# Arguments to provide to the method call.
[AllowEmptyCollection()]
[Parameter(Position = 1, ValueFromPipelineByPropertyName)]
[psobject[]]$ArgumentList = @(),
# Indicates whether the call should be static.
[Parameter(ValueFromPipelineByPropertyName)]
[switch]$Static,
# Input object to invoke the method on.
[Parameter(ValueFromPipeline, Mandatory, Position = 2)]
$InputObject
)
# dynamicParam {
# 'dynamicParam', $InputObject, $_, $PSBoundParameters | Out-String | Out-Host
# if($null -ne $InputObject) {
# $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
# $attributeCollection.Add([System.Management.Automation.ParameterAttribute]@{
# Mandatory = $true
# Position = 0
# ValueFromPipelineByPropertyName = $true
# })
# $attributeCollection.Add([System.Management.Automation.AliasAttribute]::new('Name', 'MethodName'))
# $attributeCollection.Add([System.Management.Automation.ValidateSetAttribute]::new(@($InputObject | Get-Member -MemberType Method -Static:$Static | Select-Object -ExpandProperty Name -Unique)))
# $attributeCollection | Out-Host
# $dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new('Method', [string], $attributeCollection)
# $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
# $paramDictionary.Add('Method', $dynParam)
# return $paramDictionary
# }
# }
process {
$sc = [scriptblock]::Create('$args[0]{1}($args[1])({0})' -f @(($ArgumentList | ForEach-Object {
'$args[2][{0}]' -f ($i++)
} | Join-String -Separator ','), ($Static ? '::' : '.')))
$sc.Invoke($InputObject, $Method, $ArgumentList ?? @($null))
}
}
我注释掉了功能失调的代码,使 cmdlet 进入工作状态。是否有任何技巧可以复制内置 cmdlet 的功能以进行自动完成?我目前正在使用最新版本的 Powershell Core 7.1.5。
解决方案
推荐阅读
- debugging - 如何在任意点工作室本地调试多个项目
- python - 如何使用 pytest 选项作为夹具而不重复自己?
- python - 根据列值拆分 Python 数据框,然后在算法中使用它们
- cognos - Cognos Framework Manager 中的错误 -XQE-PLN-0229
- javascript - InversifyJS @multiInject 键值映射
- java - 为库包声明类时出现 IllegalAccessError
- javascript - 如何在 WordPress 页面中按 id 隐藏和显示 div 元素?
- react-native - React Native 加载 Delight VR 视频播放器
- c - 按 (.,!,?) 分割数组
- unity3d - 实例化制作多个克隆