PowerShell - 如何用单引号将 argumentcompleter 自动完成参数(包含空格)括起来?

问题描述 投票:0回答:1

我正在做一个简单的演示来说明函数中的 ArgumentCompleter 属性,这是我迄今为止正在使用的代码:

#Requires -Modules Hyper-V
#Requires -RunAsAdministrator
function Get-VMNameTest
{
    param (
        [ArgumentCompleter({
            param ($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
            $VmNameArg = (Get-VM).Name | Where-Object {$_.Name -like "*$WordToComplete*"}
            *foreach ($vm in $VmNameArg)
            *{
            *    if ($vm -match '\s+')
            *    {
            *        "'" + $vm + "'"
            *    }
            *    else {$vm}
            *}
        })]
        [string[]]$Name
    )

    foreach ($vm in $Name)
    {
        Write-Output "VMName:  $vm"
    }
}

-Name
参数将自动补全在本地计算机上找到的任何虚拟机(名称)。我添加了一个 foreach 循环(用 * 表示),以在任何包含空格的虚拟机名称周围添加单引号 - 否则,命令行上显示的虚拟机名称(包含空格)将不带引号。

当使用

CTRL + SPACE
查看自动完成值时,本机 cmdlet 在列表中显示不带单引号的值(包含空格),但是只要您在带有空格的值上使用箭头键,它就会自动添加单引号对命令行进行引号(在本例中,它使用 .\ 和尾随
\
显示为路径。举例说明:
PS C:\> Get-Item -Path '.\Program Files\'
$Recycle.Bin               System Volume Information
Documents and Settings     Users
Program Files              Windows
Program Files (x86)
ProgramData

(在此示例中通过箭头键选择“程序文件”)。


这就是我的代码在 foreach 循环中的显示方式 - 单引号同时出现在列表和命令行中:

PS C:\> Get-VMNameTest -Name 'Server Two' ServerOne 'Server Two'

如果没有 foreach 循环,单引号不会用空格包围值(这显然是有问题的):


PS C:\> Get-VMNameTest -Name Server Two ServerOne Server Two

我试图与本机 cmdlet 的行为保持一致,所以这就是我想要实现的目标:


PS C:\> Get-VMNameTest -Name 'Server Two' ServerOne Server Two

显然,本机(编译的)cmdlet 的行为方式和添加单引号(或添加路径分隔符、转义必要字符等)的逻辑存在差异。 虽然这是一个微小的外观差异,但我想知道是否有更好的方法来解决这个问题。 高手是怎么做到的?

powershell autocomplete single-quotes
1个回答
2
投票
未加引号

,但是当选择一个项目时,应该加引号,如果是这种情况,那么您可以使用CompletionResult(String, String, CompletionResultType, String)重载来完成它

using namespace System.Management.Automation using namespace System.Management.Automation.Language using namespace System.Collections $registerArgumentCompleterSplat = @{ ParameterName = 'Test' CommandName = 'Test-Completion' } Register-ArgumentCompleter @registerArgumentCompleterSplat -ScriptBlock { param ( [string] $CommandName, [string] $ParameterName, [string] $WordToComplete, [CommandAst] $CommandAst, [IDictionary] $FakeBoundParameters ) # generate a list of items here for testing, # some can have spaces, others dont $list = 0..10 | ForEach-Object { if ($_ % 2) { return "Item $_" }; "Item$_" } # completion logic foreach ($item in $list) { if (-not $item.StartsWith($wordToComplete, [StringComparison]::InvariantCultureIgnoreCase)) { continue } $completionText = [CodeGeneration]::EscapeSingleQuotedStringContent($item) # if this item has white space if ($item -match '\s') { $completionText = "'" + $completionText + "'" } [CompletionResult]::new( $completionText, $item, [CompletionResultType]::ParameterValue, 'some tooltip here if you want') } } function Test-Completion { param( [Parameter(Mandatory)] [string] $Test ) $Test }

	
© www.soinside.com 2019 - 2024. All rights reserved.