如何从 PowerShell 调用复杂的 COM 方法? [英] How to call a complex COM method from PowerShell?

查看:17
本文介绍了如何从 PowerShell 调用复杂的 COM 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用命名参数从 PowerShell 调用 COM 方法?我正在使用的 COM 对象方法有几十个参数:

Is it possible to call a COM method from PowerShell using named parameters? The COM object method I am working with has dozens of parameters:

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 模块的 Visual Basic 或 Python 中,您可以使用命名参数来仅指定您需要的选项子集.例如(在 Python 中):

Most of those parameters are optional and some of them are mutually exclusive. In Visual Basic or Python using the win32com module you can use named parameters to specify only the subset of options you need. For example (in 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)

我不知道如何以同样的方式从 PowerShell 调用这个对象.

I can't figure out how to call this object from PowerShell in the same way.

推荐答案

这个问题确实让我感兴趣,所以我做了一些真正的挖掘,我找到了解决方案(虽然我只测试了一些简单的案例)!

This problem did interest me, so I did some real digging and I have found a solution (though I have only tested on some simple cases)!

概念

关键的解决方案是使用 [System.Type]::InvokeMember,它允许您在其重载之一中传递参数名称.

The key solution is using [System.Type]::InvokeMember which allows you to pass parameter names in one of its overloads.

这是基本概念.

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

解决方案

这是一个可重用的解决方案,用于调用带有命名参数的方法.这应该适用于任何对象,而不仅仅是 COM 对象.我制作了一个哈希表作为参数之一,以便指定命名参数会更自然,并希望更不容易出错.如果需要,也可以使用 -Argument 参数调用不带参数名称的方法

Here is a reusable solution for calling methods with named parameters. This should work on any object, not just COM objects. I made a hashtable as one of the parameters so that specifying the named parameters will be more natural and hopefully less error prone. You can also call a method without parameter names if you want by using the -Argument parameter

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

示例

使用命名参数调用方法.

Calling a method with named parameters.

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

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

调用不带参数的方法(您也可以将 -Argument 与 $null 一起使用).

Calling a method that takes no parameters (you can also use -Argument with $null).

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

这篇关于如何从 PowerShell 调用复杂的 COM 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆