是否可以使用命名参数从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 )
这些参数中的大多数是可选的,其中一些是互斥的。在使用win32com模块的Visual Basic或Python中,您可以使用命名参数来仅指定所需选项的子集。例如(在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调用此对象。
答案 0 :(得分:31)
这个问题确实让我感兴趣,所以我做了一些真正的挖掘,我找到了一个解决方案(虽然我只测试了一些简单的情况)!
<强>概念强>
关键解决方案是使用[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"}
调用不带参数的方法(你也可以使用带有$ null的-Argument)。
$shell = New-Object -ComObject Shell.Application
Invoke-NamedParameter $Shell "MinimizeAll" @{}