it-source

PowerShell에서 복잡한 COM 방식을 호출하는 방법은?

criticalcode 2023. 9. 23. 22:46
반응형

PowerShell에서 복잡한 COM 방식을 호출하는 방법은?

명명된 파라미터를 사용하여 파워쉘에서 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에서 이 개체를 같은 방식으로 호출하는 방법을 알 수 없습니다.

이 문제는 저에게 흥미가 있었기 때문에, 저는 진짜로 땅을 파보았고 해결책을 찾았습니다 (몇 가지 간단한 사례에 대해서만 테스트했지만)!

개념.

핵심 솔루션은 다음과 같이 사용하는 것입니다.[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" @{}

Invoke-NamedParameter 함수를 사용하는 것은 저에게 효과가 없었습니다.저는 여기 https://community.idera.com/database-tools/powershell/ask_the_experts/f/powershell_for_windows-12/6361/excel-spreadsheet-export 에서 흥미로운 해결책을 찾을 수 있었고, 그것은 저에게 효과가 있었습니다.

        $excel = New-Object -ComObject excel.application
        $objMissingValue = [System.Reflection.Missing]::Value
        $Workbook = $excel.Workbooks.Open($datafile,$objMissingValue,$False,$objMissingValue,$objMissingValue,$objMissingValue,$true,$objMissingValue)

제가 사용하지 않은 파라미터는 결측값을 추가했습니다.

언급URL : https://stackoverflow.com/questions/5544844/how-to-call-a-complex-com-method-from-powershell

반응형