2013-02-13 11 views
12

Come si implementa il completamento della scheda dei parametri per le funzioni PowerShell oi cmdlet come Get-Service e Get-Process in PowerShell 3.0?Completamento della scheda del valore del parametro del cmdlet di PowerShell

Mi rendo conto che ValidateSet funziona per un elenco noto, ma voglio generare l'elenco su richiesta.

Adam Driscoll hints that it is possible per i cmdlet ma purtroppo non è stato elaborato.

Trevor Sullivan shows a technique per le funzioni, ma a quanto ho capito, il suo codice genera solo l'elenco al momento della definizione della funzione.

+0

Hai letto qui: http://www.powertheshell.com/dynamicargumentcompletion/ –

+0

No, non l'avevo trovato. Molto informativo –

+0

Puoi anche dare un'occhiata a http: //powertab.codeplex.com/è un 'intellissense dinamico' da powershell v.2 ma lo uso anche in 3.0 molto fine –

risposta

2

Classicamente, ho usato espressioni regolari.

per esempio,

function TabExpansion { 

    param($line, $lastWord) 

    if ($line -match '(-(\w+))\s+([^-]*$)') 
    { 
    ### Resolve Command name & parameter name 
     $_param = $matches[2] + '*' 
     $_opt = $Matches[3].Split(" ,")[-1] + '*' 
     $_base = $Matches[3].Substring(0,$Matches[3].Length-$Matches[3].Split(" ,")[-1].length) 

     $_cmdlet = [regex]::Split($line, '[|;=]')[-1] 

     if ($_cmdlet -match '\{([^\{\}]*)$') 
     { 
      $_cmdlet = $matches[1] 
     } 

     if ($_cmdlet -match '\(([^()]*)$') 
     { 
      $_cmdlet = $matches[1] 
     } 

     $_cmdlet = $_cmdlet.Trim().Split()[0] 

     $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet)[0] 

     while ($_cmdlet.CommandType -eq 'alias') 
     { 
      $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet.Definition)[0] 
     } 

    ### Currently target is Get-Alias & "-Name" parameter 

     if ("Get-Alias" -eq $_cmdlet.Name -and "Name" -like $_param) 
     { 
      Get-Alias -Name $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') } 
      break; 
     } 
    } 
} 

Riferimento http://gallery.technet.microsoft.com/scriptcenter/005d8bc7-5163-4a25-ad0d-25cffa90faf5


Posh-git rinomina TabExpansion a TabExpansionBackup in GitTabExpansion.ps1.
E TabExpansion rideterminato di posh-git chiama TabExpansion originale (TabExpansionBackup) quando i completamenti non corrispondono ai comandi git.
Quindi tutto ciò che dovete fare è ridefinire TabExpansionBackup.

(cat \ GitTabExpansion.ps1 |. Selezionare -Last 18)
============================== GitTabExpansion ps1 ==============================

if (Test-Path Function:\TabExpansion) { 
    Rename-Item Function:\TabExpansion TabExpansionBackup 
} 

function TabExpansion($line, $lastWord) { 
    $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() 

    switch -regex ($lastBlock) { 
     # Execute git tab completion for all git-related commands 
     "^$(Get-AliasPattern git) (.*)" { GitTabExpansion $lastBlock } 
     "^$(Get-AliasPattern tgit) (.*)" { GitTabExpansion $lastBlock } 

     # Fall back on existing tab expansion 
     default { if (Test-Path Function:\TabExpansionBackup) { TabExpansionBackup $line $lastWord } } 
    } 
} 

=========== ================================================== ==================

Ridefinizione TabExpansionBackup (TabExpansion originale)

function TabExpansionBackup { 
    ... 

    ### Resolve Command name & parameter name 

    ... 

    ### Currently target is Get-Alias & "-Name" parameter 

    ... 
} 
+0

Vedo che posh-git ha già definito questa funzione nel mio ambiente. C'è un modo per estendere/sottoclasse qualsiasi definizione esistente? –

7

Rimasi perplesso per un po ', perché volevo fare la stessa cosa. Ho messo insieme qualcosa di cui sono davvero felice.

È possibile aggiungere attributi ValidateSet da un DynamicParam. Ecco un esempio di dove ho generato il mio ValidateSet al volo da un file xml. Vedere la "ValidateSetAttribute" nel codice seguente:

function Foo() { 
    [CmdletBinding()] 
    Param() 
    DynamicParam { 
     # 
     # The "modules" param 
     # 
     $modulesAttributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute] 

     # [parameter(mandatory=..., 
     #  ... 
     #)] 
     $modulesParameterAttribute = new-object System.Management.Automation.ParameterAttribute 
     $modulesParameterAttribute.Mandatory = $true 
     $modulesParameterAttribute.HelpMessage = "Enter one or more module names, separated by commas" 
     $modulesAttributeCollection.Add($modulesParameterAttribute)  

     # [ValidateSet[(...)] 
     $moduleNames = @() 
     foreach($moduleXmlInfo in Select-Xml -Path "C:\Path\to\my\xmlFile.xml" -XPath "//enlistment[@name=""wp""]/module") { 
      $moduleNames += $moduleXmlInfo.Node.Attributes["name"].Value 
     } 
     $modulesValidateSetAttribute = New-Object -type System.Management.Automation.ValidateSetAttribute($moduleNames) 
     $modulesAttributeCollection.Add($modulesValidateSetAttribute) 

     # Remaining boilerplate 
     $modulesRuntimeDefinedParam = new-object -Type System.Management.Automation.RuntimeDefinedParameter("modules", [String[]], $modulesAttributeCollection) 

     $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 
     $paramDictionary.Add("modules", $modulesRuntimeDefinedParam) 
     return $paramDictionary 
    } 
    process { 
     # Do stuff 
    } 
} 

Con questo, posso digitare

Foo -modules M<press tab> 

e sarà scheda-complete "MarcusModule" se questo modulo è stato nel file XML. Inoltre, posso modificare il file XML e il comportamento di completamento della tabulazione cambierà immediatamente; non è necessario reimportare la funzione.

+0

Funziona alla grande. Grazie. – majkinetor

+0

http://stackoverflow.com/a/23001637/288393 –

Problemi correlati