2011-04-04 31 views
23

Có thể gọi phương thức COM từ PowerShell bằng các tham số được đặt tên không? Phương thức đối tượng COM mà tôi đang làm việc với hàng tá tham số:Làm thế nào để gọi một phương thức COM phức tạp từ PowerShell?

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) 

Hầu hết các tham số đó là tùy chọn và một số tham số loại trừ lẫn nhau. Trong Visual Basic hoặc Python sử dụng mô-đun win32com, bạn có thể sử dụng các tham số có tên để chỉ định tập con các tùy chọn bạn cần. Ví dụ: (bằng Python):

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) 

Tôi không thể tìm ra cách gọi đối tượng này từ PowerShell theo cùng một cách.

+1

Kêu gọi tìm một câu hỏi rất khó. Tôi có một giải pháp cuối cùng. Nhưng trước tiên tôi sẽ đi tìm một cái tủ để cuộn tròn và khóc trong giấc ngủ. – JasonMArcher

Trả lời

30

Vấn đề này đã làm tôi quan tâm, vì vậy tôi đã thực hiện một số đào thực sự và tôi đã tìm thấy một giải pháp (mặc dù tôi đã chỉ được thử nghiệm trên một số trường hợp đơn giản)!

Concept

Các giải pháp chính được sử dụng [System.Type]::InvokeMember cho phép bạn vượt qua tên tham số trong một trong những quá tải của nó.

Đây là khái niệm cơ bản.

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

Giải pháp

Dưới đây là một giải pháp tái sử dụng để gọi các phương pháp với các thông số được đặt tên. Điều này sẽ làm việc trên bất kỳ đối tượng, không chỉ đối tượng COM. Tôi đã thực hiện một hashtable như là một trong các tham số để xác định các tham số được đặt tên sẽ tự nhiên hơn và hy vọng ít lỗi dễ bị. Bạn cũng có thể gọi một phương thức không có tên tham số nếu bạn muốn bằng cách sử dụng tham số -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 
      ) 
     } 
    } 
} 

Ví dụ

Gọi một phương pháp với các thông số được đặt tên.

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

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

Gọi một phương pháp mà không có thông số (bạn cũng có thể sử dụng -Argument với $ null).

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

Đây là một giải pháp tuyệt vời. – klumsy

+0

Chà. Cảm ơn. Tôi sẽ thử nghiệm vào ngày mai. – David

+0

Làm tốt lắm, Jason. – x0n

Các vấn đề liên quan