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

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

问题描述

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

  object.GridData(DataFile,xCol,yCol,zCol,ExclusionFilter ,DupMethod,xDupTol,
yDupTol,NUMCOLS,其行,XMIN,XMAX,YMIN,YMAX,算法,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)

大多数参数是可选的,其中一些是互斥的。在Visual Basic或Python中使用win32com模块,您可以使用命名参数仅指定所需的选项子集。例如(在Python中):

  Surfer.GridData(DataFile = InFile,
xCol = Options.xCol,
yCol = Options.yCol,
zCol = Options.zCol,
DupMethod = win32com.client.constants.srfDupMedZ,
xDupTol = Options.GridSpacing,
yDupTol =选项.GridSpacing,
NUMCOLS = NUM​​COLS,
=其行其行,
XMIN = XMIN,
XMAX = XMAX,
YMIN = YMIN,
YMAX = YMAX ,
算法= win32com.client.constants.srfMovingAverage,
ShowReport =假,
SearchEnable = TRUE,
SearchRad1 = Options.SearchRadius,
SearchRad2 = Options.SearchRadius ,
SearchMinData = 5,
OutGrid = OutGrid)

找到如何从PowerShell以相同的方式调用此对象。

解决方案

这个问题对我有兴趣,所以我做了一些真正的挖掘和我找到一个解决方案(虽然我只测试了一些简单的情况下)!



概念



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



这里是基本概念。

  $ Object.GetType()。InvokeMember $ Method,[System.Reflection.BindingFlags] :: InvokeMethod,
$ null,## Binder
$ Object,## Target
([Object []] $ Args),## Args
$ null,##修饰符
$ null,##文化
([String []] $ NamedParameters)## NamedParameters



解决方案



使用命名参数调用方法。这应该工作在任何对象,而不只是COM对象。我做了一个散列表作为参数之一,以便指定命名的参数将更自然,希望减少错误倾向。如果您想使用-Argument参数

  Function Invoke-NamedParameter {$ b $参数(ParameterSetName =Named,Position = 0,Mandatory = $ true)] 
[Parameter(ParameterSetName =Named位置= 0,强制= $ true)]
[ValidateNotNull()]
[System.Object] $ Object

[ParameterSetName = ,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不支持管道
if($ PSCmdlet.ParameterSetName -eqNamed){
##调用具有参数名称的方法
##注意:这里可以使用散列表,因为键(参数名)和值(args)
##将以相同的顺序输出。我们不需要担心顺序,只要
##所有参数都有名称
$ Object.GetType()。InvokeMember($ Method,[System.Reflection.BindingFlags] :: InvokeMethod,
$ null,## Binder
$ Object,##目标
([Object []]($ Parameter.Values)),## Args
$ null,##修饰符
$ null,##文化
([String []]($ Parameter.Keys))## NamedParameters

} else {
## Invoke没有参数名的方法
$ Object.GetType()。InvokeMember($ Method,[System.Reflection.BindingFlags] :: InvokeMethod,
$ null,## Binder
$ Object,##目标
$参数,## Args
$ null,##修饰符
$ null,##文化
$ null ## NamedParameters

}
}
}

示例 >

使用命名参数调用方法。

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

##多个语法的语法为@ {First =foo;Second=bar}

调用不带参数的方法你也可以使用-Argument with $ null)。

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


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 )

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)

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

Concept

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

Here is the basic concept.

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

Solution

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

Examples

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

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天全站免登陆