2013-02-13 19 views
12

पावरशेल फ़ंक्शंस या cmdlets के लिए पैरामीटर टैब पूर्णता को कैसे कार्यान्वित करें जैसे PowerShell 3.0 में Get-Service और Get-Process?पावरशेल cmdlet पैरामीटर मान टैब पूर्णता

मुझे पता है कि ValidateSet एक ज्ञात सूची के लिए काम करता है, लेकिन मैं मांग पर सूची उत्पन्न करना चाहता हूं।

एडम ड्रिस्कॉल hints that it is possible cmdlets के लिए लेकिन दुर्भाग्य से विस्तारित नहीं किया गया है।

ट्रेवर सुलिवान shows a technique फ़ंक्शंस के लिए, लेकिन जैसा कि मैं इसे समझता हूं, उसका कोड केवल उस कार्य को उत्पन्न करता है जब फ़ंक्शन परिभाषित किया जाता है।

+0

क्या आपने यहां पढ़ा है: http://www.powertheshell.com/dynamicargumentcompletion/ –

+0

नहीं, मुझे यह नहीं मिला था। बहुत जानकारीपूर्ण –

+0

आप http: //powertab.codeplex पर भी एक नज़र डाल सकते हैं।कॉम/यह पावरहेल v.2 से 'गतिशील इंटेलिसेंस' है, लेकिन इसे 3.0 में भी बहुत अच्छा लगता है –

उत्तर

2

शास्त्रीय आधार पर, मैं regex का इस्तेमाल किया।

उदाहरण के लिए

,

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; 
     } 
    } 
} 

संदर्भ http://gallery.technet.microsoft.com/scriptcenter/005d8bc7-5163-4a25-ad0d-25cffa90faf5


पॉश-Git GitTabExpansion.ps1 में TabExpansionBackup को TabExpansion नाम बदलता है।
और पॉश-गिट की पुनर्वितरित टैबएक्सपेंशन मूल टैबएक्सप्शन (टैबएक्सपेंशनबैकअप) को कॉल करता है जब पूर्णता गिट कमांड से मेल नहीं खाती है।
तो आपको केवल TabExpansionBackup को फिर से परिभाषित करना है।

(बिल्ली \ GitTabExpansion.ps1 |। -पिछले चयन 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 } } 
    } 
} 

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

को फिर से परिभाषित TabExpansionBackup (मूल TabExpansion)

function TabExpansionBackup { 
    ... 

    ### Resolve Command name & parameter name 

    ... 

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

    ... 
} 
+0

मुझे लगता है कि पॉश-गिट ने पहले से ही मेरे पर्यावरण में इस फ़ंक्शन को परिभाषित कर दिया है। क्या किसी मौजूदा परिभाषा को विस्तार/उप-श्रेणी का विस्तार करने का कोई तरीका है? –

7

मैंने थोड़ी देर के लिए इस पर परेशान किया, क्योंकि मैं वही काम करना चाहता था। मैंने कुछ ऐसा किया जो मैं वास्तव में खुश हूं।

आप डायनामिक पैराम से वैलिडेटेट गुण जोड़ सकते हैं। यहां एक उदाहरण दिया गया है जहां मैंने एक XML फ़ाइल से अपने ValidateSet ऑन-द-फ्लाई को जेनरेट किया है। मैं

Foo -modules M<press tab> 

टाइप कर सकते हैं और यह टैब-पूरा "MarcusModule" अगर उस मॉड्यूल एक्सएमएल फ़ाइल में था होगा,

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 
    } 
} 
इसी के साथ

: "ValidateSetAttribute" निम्न कोड में देखें। इसके अलावा, मैं एक्सएमएल फ़ाइल को संपादित कर सकता हूं और टैब-समापन व्यवहार तुरंत बदल जाएगा; आपको फ़ंक्शन को फिर से आयात करने की आवश्यकता नहीं है।

+0

यह बहुत अच्छा काम करता है। धन्यवाद। – majkinetor

+0

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