about_Functions_Argument_Completion

Korte beschrijving

Voltooiing van argumenten is een functie van PowerShell die hints biedt, detectie mogelijk maakt en invoerinvoer van argumentwaarden versnelt.

Lange beschrijving

In dit artikel worden de verschillende manieren beschreven waarop u argumentvervolledigers voor PowerShell-functies kunt implementeren. Argument completers bieden de mogelijke waarden voor een parameter. De beschikbare waarden worden tijdens runtime berekend wanneer de gebruiker op de Tab-toets drukt na de parameternaam. Er zijn verschillende manieren om een argument completer voor een parameter te definiëren.

Notitie

Tab is de standaardsleutelbinding in Windows. Deze sleutelbinding kan worden gewijzigd door de PSReadLine-module of de toepassing die als host fungeert voor PowerShell. De sleutelbinding verschilt op niet-Windows-platforms. Zie about_PSReadLine voor meer informatie.

ValidateSet-kenmerk

Het kenmerk ValidateSet geeft een set geldige waarden op voor een parameter of variabele en schakelt tabvoltooiing in. PowerShell genereert een fout als een parameter of variabele waarde niet overeenkomt met een waarde in de set. In het volgende voorbeeld kan de waarde van de parameter Fruit alleen Apple, Banana of Pear zijn.

Param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('Apple', 'Banana', 'Pear')]
    [string[]]
    $Fruit
)

In het volgende voorbeeld moet de waarde van de variabele $flavor Chocolade, Aardbeien of Vanille zijn. Het ValidateSet kenmerk kan worden gebruikt voor elke variabele, niet alleen parameters.

[ValidateSet('Chocolate', 'Strawberry', 'Vanilla')]
[string]$flavor = 'Strawberry'

De validatie vindt plaats wanneer die variabele zelfs binnen het script wordt toegewezen.

Param(
    [ValidateSet('hello', 'world')]
    [string]$Message
)

$Message = 'bye'

In dit voorbeeld wordt de volgende fout geretourneerd tijdens runtime:

MetadataError: The attribute cannot be added because variable Message with
value bye would no longer be valid.

Zie about_Tab_Expansion voor meer informatie over tabbladuitbreiding.

Dynamic ValidateSet-waarden met behulp van klassen

U kunt een klasse gebruiken om de waarden dynamisch te genereren voor ValidateSet tijdens runtime. In het volgende voorbeeld worden de geldige waarden voor de variabele $Sound gegenereerd via een klasse met de naam SoundNames die drie bestandssysteempaden controleert op beschikbare geluidsbestanden:

Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
    [string[]] GetValidValues() {
        $SoundPaths = '/System/Library/Sounds/',
                      '/Library/Sounds',
                      '~/Library/Sounds'
        $SoundNames = ForEach ($SoundPath in $SoundPaths) {
            If (Test-Path $SoundPath) {
                (Get-ChildItem $SoundPath).BaseName
            }
        }
        return [string[]] $SoundNames
    }
}

De [SoundNames] klasse wordt vervolgens als volgt geïmplementeerd als een dynamische ValidateSet-waarde :

Param(
    [ValidateSet([SoundNames])]
    [string]$Sound
)

Notitie

De IValidateSetValuesGenerator klasse is geïntroduceerd in PowerShell 6.0.

Kenmerk ArgumentCompletions

Met het kenmerk ArgumentCompletions kunt u tabvoltooiingswaarden toevoegen aan een specifieke parameter. Er moet een kenmerk ArgumentCompletions worden gedefinieerd voor elke parameter die tabvoltooiing nodig heeft. Het kenmerk ArgumentCompletions is vergelijkbaar met ValidateSet. Bij beide kenmerken wordt een lijst met waarden weergegeven wanneer de gebruiker op Tab drukt na de parameternaam. In tegenstelling tot ValidateSet worden de waarden echter niet gevalideerd en lijken ze meer op suggesties. Daarom kan de gebruiker elke waarde opgeven, niet alleen de waarden in de lijst.

Het kenmerk ArgumentCompletions mag niet worden verward met het kenmerk ArgumentCompleter , waarvoor een scriptblok nodig is om de opties te definiëren. de opgegeven waarden beschikbaar zijn

De syntaxis is als volgt:

function Test-ArgumentCompletions {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ArgumentCompletions('Fruits', 'Vegetables')]
        $Type,

        [Parameter()]
        [ArgumentCompletions('Apple', 'Banana', 'Orange')]
        $Fruit,

        [Parameter()]
        [ArgumentCompletions('Onion', 'Carrot', 'Lettuce')]
        $Vegetable
    )
}

Elk van de parameters wordt een lijst met opties opgegeven voor het kenmerk ArgumentCompletions om tabvoltooiing in te schakelen.

Dit kenmerk is geïntroduceerd in PowerShell 6.0.

Kenmerk ArgumentCompleter

Met het kenmerk ArgumentCompleter kunt u tabvoltooiingswaarden toevoegen aan een specifieke parameter. Er moet een kenmerk ArgumentCompleter worden gedefinieerd voor elke parameter die tabvoltooiing nodig heeft.

Als u een kenmerk ArgumentCompleter wilt toevoegen, moet u een scriptblok definiëren dat de waarden bepaalt. Het scriptblok moet de volgende parameters in de onderstaande volgorde hebben. De namen van de parameter maken niet uit omdat de waarden positioneel worden opgegeven.

De syntaxis is als volgt:

function MyArgumentCompleter {
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
            param ( $commandName,
                    $parameterName,
                    $wordToComplete,
                    $commandAst,
                    $fakeBoundParameters )
            # Perform calculation of tab completed values here.
        } )]
        $ParamName
    )
}

Scriptblok ArgumentCompleter

De parameters van het scriptblok zijn ingesteld op de volgende waarden:

  • $commandName (Positie 0) - Deze parameter is ingesteld op de naam van de opdracht waarvoor het scriptblok tabvoltooiing biedt.
  • $parameterName (Positie 1) - Deze parameter is ingesteld op de parameter waarvan de waarde tabvoltooiing vereist.
  • $wordToComplete(Positie 2) - Deze parameter is ingesteld op de waarde die de gebruiker heeft opgegeven voordat hij op Tab drukt. Uw scriptblok moet deze waarde gebruiken om de waarden voor tabvoltooiing te bepalen.
  • $commandAst (Positie 3) - Deze parameter is ingesteld op de AST (Abstract Syntax Tree) voor de huidige invoerregel. Zie de ast-typedocumentatie voor meer informatie.
  • $fakeBoundParameters(Positie 4) - Deze parameter is ingesteld op een hashtabel die de $PSBoundParameters cmdlet bevat, voordat de gebruiker op Tab drukt. Zie about_Automatic_Variables voor meer informatie.

Het scriptblok ArgumentCompleter moet de waarden uitschrijven met behulp van de pijplijn, zoals ForEach-Object, Where-Objectof een andere geschikte methode. Als u een matrix met waarden retourneert, wordt de hele matrix door PowerShell behandeld als een voltooiingswaarde van één tabblad.

In het volgende voorbeeld wordt tabvoltooiing toegevoegd aan de parameter Waarde . Als alleen de parameter Waarde is opgegeven, worden alle mogelijke waarden of argumenten voor Waarde weergegeven. Wanneer de parameter Type is opgegeven, geeft de parameter Waarde alleen de mogelijke waarden voor dat type weer.

Bovendien zorgt de -like operator ervoor dat als de gebruiker de volgende opdracht typt en tabvoltooiing gebruikt, alleen Apple wordt geretourneerd.

Test-ArgumentCompleter -Type Fruits -Value A

function MyArgumentCompleter{
    param ( $commandName,
            $parameterName,
            $wordToComplete,
            $commandAst,
            $fakeBoundParameters )

    $possibleValues = @{
        Fruits = @('Apple', 'Orange', 'Banana')
        Vegetables = @('Onion', 'Carrot', 'Lettuce')
    }

    if ($fakeBoundParameters.ContainsKey('Type')) {
        $possibleValues[$fakeBoundParameters.Type] | Where-Object {
            $_ -like "$wordToComplete*"
        }
    } else {
        $possibleValues.Values | ForEach-Object {$_}
    }
}

function Test-ArgumentCompleter {
[CmdletBinding()]
 param (
        [Parameter(Mandatory=$true)]
        [ValidateSet('Fruits', 'Vegetables')]
        $Type,

        [Parameter(Mandatory=$true)]
        [ArgumentCompleter({ MyArgumentCompleter @args })]
        $Value
      )
}

Op klassen gebaseerd argument completers

Vanaf PowerShell 7.2 is een nieuwe functie toegevoegd waarmee u algemenere implementaties van geparameteriseerde argument completers kunt definiëren.

Door hiervan af te leiden ArgumentCompleterAttribute, is het mogelijk om algemene completers te maken die kunnen worden hergebruikt, bijvoorbeeld:

[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]

[DateCompleter(WeekDay='Monday', From="LastYear")]

[GitCommits(Branch='release')]

De afgeleide kenmerken moeten de IArgumentCompleterFactory interface implementeren en eigenschapswaarden gebruiken om een gespecialiseerde completer te maken.

using namespace System.Collections
using namespace System.Collections.Generic
using namespace System.Management.Automation
using namespace System.Management.Automation.Language

class NumberCompleter : IArgumentCompleter {

    [int] $From
    [int] $To
    [int] $Step

    NumberCompleter([int] $from, [int] $to, [int] $step) {
        if ($from -gt $to) {
            throw [ArgumentOutOfRangeException]::new("from")
        }
        $this.From = $from
        $this.To = $to
        $this.Step = $step -lt 1 ? 1 : $step
    }

    [IEnumerable[CompletionResult]] CompleteArgument(
        [string] $CommandName,
        [string] $parameterName,
        [string] $wordToComplete,
        [CommandAst] $commandAst,
        [IDictionary] $fakeBoundParameters) {

        $resultList = [List[CompletionResult]]::new()
        $local:to = $this.To
        $local:step = $this.Step
        for ($i = $this.From; $i -lt $to; $i += $step) {
            $resultList.Add([CompletionResult]::new($i.ToString()))
        }

        return $resultList
    }
}

class NumberCompletionsAttribute : ArgumentCompleterAttribute, IArgumentCompleterFactory {
    [int] $From
    [int] $To
    [int] $Step

    NumberCompletionsAttribute([int] $from, [int] $to, [int] $step) {
        $this.From = $from
        $this.To = $to
        $this.Step = $step
    }

    [IArgumentCompleter] Create() { return [NumberCompleter]::new($this.From, $this.To, $this.Step) }
}

Het gebruik van PowerShell zou dan het volgende zijn:

function Add{
    param(
       [NumberCompletions(0, 100, 5)]
       [int] $X,

       [NumberCompletions(0, 100, 5)]
       [int] $Y
    )
    $X + $Y
}

Register-ArgumentCompleter

De Register-ArgumentCompleter cmdlet registreert een aangepaste argument completer. Met een argument completer kunt u dynamische tabvoltooiing opgeven, tijdens runtime voor elke opdracht die u opgeeft.

Zie Register-ArgumentCompleter voor meer informatie.

Zie ook