Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从PowerShell调用复杂的COM方法?_Com_Powershell - Fatal编程技术网

如何从PowerShell调用复杂的COM方法?

如何从PowerShell调用复杂的COM方法?,com,powershell,Com,Powershell,是否可以使用命名参数从PowerShell调用COM方法?我正在使用的COM对象方法有几十个参数: object.GridData( DataFile, xCol, yCol, zCol, ExclusionFilter, DupMethod, xDupTol, yDupTol, NumCols, NumRows, xMin, xMax, yMin, yMax, Algorithm, ShowReport, SearchEnable, SearchNumSectors, Sear

是否可以使用命名参数从PowerShell调用COM方法?我正在使用的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 )
这些参数中的大多数是可选的,其中一些是互斥的。在使用Win32 COM模块的Visual Basic或Python中,可以使用命名参数仅指定所需选项的子集。例如(在Python中):


我不知道如何以同样的方式从PowerShell调用此对象。

这个问题确实让我感兴趣,所以我进行了一些真正的挖掘,找到了一个解决方案(尽管我只在一些简单的案例中进行了测试)

概念

关键的解决方案是使用
[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"}
调用不带参数的方法(也可以将-Argument与$null一起使用)


找到一个很难回答的问题,我很荣幸。我有一个万不得已的解决办法。但首先我要找个壁橱蜷缩在里面哭着睡觉。哇。谢谢我明天会给这个做个测试。很好!这是GitHub上的还是什么?我很想窃取你的代码并引用实际的回购协议
$shell = New-Object -ComObject Shell.Application
Invoke-NamedParameter $Shell "Explore" @{"vDir"="$pwd"}

## the syntax for more than one would be @{"First"="foo";"Second"="bar"}
$shell = New-Object -ComObject Shell.Application
Invoke-NamedParameter $Shell "MinimizeAll" @{}