如何从PowerShell调用复杂的COM方法?
是否可以使用命名参数从PowerShell调用COM方法?我正在使用的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
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" @{}