2011-04-04 12 views
23

नामित पैरामीटर का उपयोग कर PowerShell से COM विधि को कॉल करना संभव है? COM वस्तु विधि के साथ मैं काम कर रहा हूँ मापदंडों के दर्जनों है:PowerShell से एक जटिल COM विधि को कैसे कॉल करें?

object.GridData(DataFile, xCol, yCol, zCol, ExclusionFilter, DupMethod, xDupTol, 
    yDupTol, NumCols, NumRows, xMin, xMax, yMin, yMax, Algorithm, ShowReport, 
    SearchEnable, SearchNumSectors, SearchRad1, SearchRad2, SearchAngle, 
    SearchMinData, SearchDataPerSect, SearchMaxEmpty, FaultFileName, BreakFileName, 
    AnisotropyRatio, AnisotropyAngle, IDPower, IDSmoothing, KrigType, KrigDriftType, 
    KrigStdDevGrid, KrigVariogram, MCMaxResidual, MCMaxIterations, MCInternalTension, 
    MCBoundaryTension, MCRelaxationFactor, ShepSmoothFactor, ShepQuadraticNeighbors, 
    ShepWeightingNeighbors, ShepRange1, ShepRange2, RegrMaxXOrder, RegrMaxYOrder, 
    RegrMaxTotalOrder, RBBasisType, RBRSquared, OutGrid, OutFmt, SearchMaxData, 
    KrigStdDevFormat, DataMetric, LocalPolyOrder, LocalPolyPower, TriangleFileName) 

उन मापदंडों के अधिकांश वैकल्पिक हैं और उनमें से कुछ परस्पर अनन्य हैं। विजुअल बेसिक या पायथन में Win32com मॉड्यूल का उपयोग करके आप नामित पैरामीटर का उपयोग केवल विकल्पों के सबसेट को निर्दिष्ट करने के लिए कर सकते हैं। उदाहरण (अजगर में) के लिए:

Surfer.GridData(DataFile=InFile, 
       xCol=Options.xCol, 
       yCol=Options.yCol, 
       zCol=Options.zCol, 
       DupMethod=win32com.client.constants.srfDupMedZ, 
       xDupTol=Options.GridSpacing, 
       yDupTol=Options.GridSpacing, 
       NumCols=NumCols, 
       NumRows=NumRows, 
       xMin=xMin, 
       xMax=xMax, 
       yMin=yMin, 
       yMax=yMax, 
       Algorithm=win32com.client.constants.srfMovingAverage, 
       ShowReport=False, 
       SearchEnable=True, 
       SearchRad1=Options.SearchRadius, 
       SearchRad2=Options.SearchRadius, 
       SearchMinData=5, 
       OutGrid=OutGrid) 

मैं समझ नहीं कैसे एक ही तरह से PowerShell से इस वस्तु कॉल करने के लिए।

+1

एक बहुत कठिन सवाल खोजने पर कुडोस। मेरे पास अंतिम उपाय का समाधान है। लेकिन सबसे पहले मुझे सोने के लिए कुरकुरा करने और रोने के लिए एक कोठरी मिल जाएगी। – JasonMArcher

उत्तर

30

इस समस्या ने मुझे रूचि दी, इसलिए मैंने कुछ वास्तविक खुदाई की और मुझे एक समाधान मिला है (हालांकि मैंने केवल कुछ साधारण मामलों पर परीक्षण किया है)!

संकल्पना

कुंजी समाधान [System.Type]::InvokeMember जो आप अपने भार के में से एक में पैरामीटर नाम पारित करने के लिए अनुमति देता है का उपयोग कर रहा है।

यहां मूल अवधारणा है।

$Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod, 
    $null, ## Binder 
    $Object, ## Target 
    ([Object[]]$Args), ## Args 
    $null, ## Modifiers 
    $null, ## Culture 
    ([String[]]$NamedParameters) ## NamedParameters 
) 

समाधान

यहाँ नामित मानकों के साथ तरीकों फोन करने के लिए एक पुन: प्रयोज्य समाधान है। यह किसी ऑब्जेक्ट पर काम करना चाहिए, न केवल COM ऑब्जेक्ट्स। मैंने पैरामीटर में से एक के रूप में एक हैशटेबल बनाया है ताकि नामित पैरामीटर निर्दिष्ट करना अधिक प्राकृतिक और उम्मीद है कि कम त्रुटि प्रवण होगी। तुम भी -Argument पैरामीटर

Function Invoke-NamedParameter { 
    [CmdletBinding(DefaultParameterSetName = "Named")] 
    param(
     [Parameter(ParameterSetName = "Named", Position = 0, Mandatory = $true)] 
     [Parameter(ParameterSetName = "Positional", Position = 0, Mandatory = $true)] 
     [ValidateNotNull()] 
     [System.Object]$Object 
     , 
     [Parameter(ParameterSetName = "Named", Position = 1, Mandatory = $true)] 
     [Parameter(ParameterSetName = "Positional", Position = 1, Mandatory = $true)] 
     [ValidateNotNullOrEmpty()] 
     [String]$Method 
     , 
     [Parameter(ParameterSetName = "Named", Position = 2, Mandatory = $true)] 
     [ValidateNotNull()] 
     [Hashtable]$Parameter 
     , 
     [Parameter(ParameterSetName = "Positional")] 
     [Object[]]$Argument 
    ) 

    end { ## Just being explicit that this does not support pipelines 
     if ($PSCmdlet.ParameterSetName -eq "Named") { 
      ## Invoke method with parameter names 
      ## Note: It is ok to use a hashtable here because the keys (parameter names) and values (args) 
      ## will be output in the same order. We don't need to worry about the order so long as 
      ## all parameters have names 
      $Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod, 
       $null, ## Binder 
       $Object, ## Target 
       ([Object[]]($Parameter.Values)), ## Args 
       $null, ## Modifiers 
       $null, ## Culture 
       ([String[]]($Parameter.Keys)) ## NamedParameters 
      ) 
     } else { 
      ## Invoke method without parameter names 
      $Object.GetType().InvokeMember($Method, [System.Reflection.BindingFlags]::InvokeMethod, 
       $null, ## Binder 
       $Object, ## Target 
       $Argument, ## Args 
       $null, ## Modifiers 
       $null, ## Culture 
       $null ## NamedParameters 
      ) 
     } 
    } 
} 

उदाहरण

नामित मानकों के साथ एक विधि कॉलिंग का उपयोग करके अगर आप चाहते हैं पैरामीटर नाम के बिना एक विधि कॉल कर सकते हैं।

$shell = New-Object -ComObject Shell.Application 
Invoke-NamedParameter $Shell "Explore" @{"vDir"="$pwd"} 

## the syntax for more than one would be @{"First"="foo";"Second"="bar"} 

ऐसी विधि को कॉल करना जो कोई पैरामीटर नहीं लेता है (आप $ null के साथ भी उपयोग कर सकते हैं) का उपयोग कर सकते हैं।

$shell = New-Object -ComObject Shell.Application 
Invoke-NamedParameter $Shell "MinimizeAll" @{} 
+0

यह एक शानदार समाधान है। – klumsy

+0

वाह। धन्यवाद। मैं इसे कल एक परीक्षा दूंगा। – David

+0

अच्छा काम, जेसन। – x0n

संबंधित मुद्दे