about_Functions_Argument_Completion
Kort beskrivning
Argumentslut är en funktion i PowerShell som ger tips, möjliggör identifiering och påskyndar indatainmatning av argumentvärden.
Lång beskrivning
Den här artikeln beskriver de olika sätt som du kan implementera argument completers för PowerShell-funktioner. Argument completers anger möjliga värden för en parameter. De tillgängliga värdena beräknas vid körning när användaren trycker på tabbtangenten efter parameternamnet. Det finns flera sätt att definiera en argument completer för en parameter.
Anteckning
Fliken är standardnyckelbindningen i Windows. Den här nyckelbindningen kan ändras av PSReadLine-modulen eller programmet som är värd för PowerShell. Nyckelbindningen skiljer sig från Windows-plattformar. Mer information finns i about_PSReadLine.
Attributet ValidateSet
Attributet ValidateSet anger en uppsättning giltiga värden för en parameter eller variabel och aktiverar tabbar. PowerShell genererar ett fel om en parameter eller ett variabelvärde inte matchar ett värde i uppsättningen. I följande exempel kan värdet för parametern Fruit bara vara Apple, Banana eller Pear.
Param(
[Parameter(Mandatory=$true)]
[ValidateSet('Apple', 'Banana', 'Pear')]
[string[]]
$Fruit
)
I följande exempel måste värdet för variabeln $flavor
vara antingen Choklad, Jordgubb eller Vanilj. Attributet ValidateSet
kan användas på valfri variabel, inte bara parametrar.
[ValidateSet('Chocolate', 'Strawberry', 'Vanilla')]
[string]$flavor = 'Strawberry'
Verifieringen sker när variabeln tilldelas även i skriptet.
Param(
[ValidateSet('hello', 'world')]
[string]$Message
)
$Message = 'bye'
Det här exemplet returnerar följande fel vid körning:
MetadataError: The attribute cannot be added because variable Message with
value bye would no longer be valid.
Mer information om flikexpansion finns i about_Tab_Expansion.
Dynamiska ValidateSet-värden med hjälp av klasser
Du kan använda en klass för att dynamiskt generera värdena för ValidateSet vid körning. I följande exempel genereras giltiga värden för variabeln $Sound
via en klass med namnet SoundNames som kontrollerar tre filsystemsökvägar efter tillgängliga ljudfiler:
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
}
}
Klassen [SoundNames]
implementeras sedan som ett dynamiskt ValidateSet-värde enligt följande:
Param(
[ValidateSet([SoundNames])]
[string]$Sound
)
Anteckning
Klassen IValidateSetValuesGenerator
introducerades i PowerShell 6.0.
Attributet ArgumentCompletions
Med attributet ArgumentCompletions kan du lägga till tabbslutvärden i en specifik parameter. Ett ArgumentCompletions-attribut måste definieras för varje parameter som behöver tabbslut. Attributet ArgumentCompletions liknar ValidateSet. Båda attributen tar en lista med värden som ska visas när användaren trycker på Tabb efter parameternamnet. Men till skillnad från ValidateSet valideras inte värdena och liknar mer förslag. Därför kan användaren ange valfritt värde, inte bara värdena i listan.
Attributet ArgumentCompletions bör inte förväxlas med attributet ArgumentCompleter, som behöver en scriptblock för att definiera alternativen. de angivna värdena är tillgängliga
Syntaxen ser ut så här:
function Test-ArgumentCompletions {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ArgumentCompletions('Fruits', 'Vegetables')]
$Type,
[Parameter()]
[ArgumentCompletions('Apple', 'Banana', 'Orange')]
$Fruit,
[Parameter()]
[ArgumentCompletions('Onion', 'Carrot', 'Lettuce')]
$Vegetable
)
}
Var och en av parametrarna tillhandahålls en lista med alternativ för attributet ArgumentCompletions för att aktivera flikslut.
Det här attributet introducerades i PowerShell 6.0.
ArgumentCompleter-attribut
Med attributet ArgumentCompleter kan du lägga till tabbslutvärden till en specifik parameter. Ett ArgumentCompleter-attribut måste definieras för varje parameter som behöver tabbslut.
Om du vill lägga till ett ArgumentCompleter-attribut måste du definiera ett skriptblock som bestämmer värdena. Skriptblocket måste ha följande parametrar i den ordning som anges nedan. Parameterns namn spelar ingen roll eftersom värdena anges positionmässigt.
Syntaxen ser ut så här:
function MyArgumentCompleter {
Param(
[Parameter(Mandatory)]
[ArgumentCompleter( {
param ( $commandName,
$parameterName,
$wordToComplete,
$commandAst,
$fakeBoundParameters )
# Perform calculation of tab completed values here.
} )]
$ParamName
)
}
ArgumentCompleter-skriptblock
Skriptblockparametrarna är inställda på följande värden:
$commandName
(Position 0) – Den här parametern är inställd på namnet på det kommando som skriptblocket tillhandahåller tabbslut.$parameterName
(Position 1) – Den här parametern är inställd på parametern vars värde kräver att fliken slutförs.$wordToComplete
(Position 2) – Den här parametern är inställd på det värde som användaren har angett innan de trycker på Tabb. Skriptblocket bör använda det här värdet för att fastställa tabbslutvärden.$commandAst
(Position 3) – Den här parametern är inställd på abstrakt syntaxträd (AST) för den aktuella indatalinjen. Mer information finns i AST-typdokumentationen.$fakeBoundParameters
(Position 4) – Den här parametern är inställd på en hashtable som innehåller$PSBoundParameters
för cmdleten innan användaren trycker på Tabb. Mer information finns i about_Automatic_Variables.
Skriptblocket ArgumentCompleter måste avregistrera värdena med pipelinen, till exempel ForEach-Object
, Where-Object
eller någon annan lämplig metod.
Om du returnerar en matris med värden behandlar PowerShell hela matrisen som ett flikslutvärde.
I följande exempel läggs flikslutningen till i parametern Value . Om endast värdeparametern anges visas alla möjliga värden eller argument för Värde . När parametern Type (Typ) anges visar parametern Value endast möjliga värden för den typen.
Dessutom ser operatorn -like
till att om användaren skriver följande kommando och använder Tab completion returneras endast Apple .
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
)
}
Class-based argument completers
Från och med PowerShell 7.2 har en ny funktion lagts till som gör att du kan definiera mer generiska implementeringar av parameteriserade argument-completers.
Genom att härleda från ArgumentCompleterAttribute
kan du skapa generiska kompletterare som kan återanvändas, till exempel:
[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]
[DateCompleter(WeekDay='Monday', From="LastYear")]
[GitCommits(Branch='release')]
De härledda attributen IArgumentCompleterFactory
måste implementera gränssnittet och använda egenskapsvärden för att skapa en specialiserad slutförare.
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) }
}
Användningen från PowerShell skulle då vara:
function Add{
param(
[NumberCompletions(0, 100, 5)]
[int] $X,
[NumberCompletions(0, 100, 5)]
[int] $Y
)
$X + $Y
}
Register-ArgumentCompleter
Cmdleten Register-ArgumentCompleter
registrerar en anpassad argument-completer.
Med en argumentkompletterare kan du ange dynamiskt tabbslut, vid körning för alla kommandon som du anger.
Mer information finns i Register-ArgumentCompleter.