【问题标题】:How can a Powershell function specify a ComObject parameter type?Powershell 函数如何指定 ComObject 参数类型?
【发布时间】:2022-06-18 20:40:09
【问题描述】:

假设我正在尝试编写一个将结果集打印到 Excel 工作表的 Powershell 函数,如下所示:

function Write-ToWorksheet {
  param (
    [Parameter( Position = 0, Mandatory = $true )]
    [MyLibrary.MyCustomResultType[]]
    $ResultSet,

    [Parameter( Position = 1, Mandatory = $true )]
    [Excel.Worksheet]
    $Worksheet
  )
  # ... Implementation goes here ...
}

假设我以这样的方式调用它:

$excel = New-Object -ComObject Excel.Application
$wb = $excel.Workbooks.Add()

$results = Get-MyResults # Never mind what this does.

Write-ToWorksheet -ResultSet $results -Worksheet $wb.Sheets[ 1 ]

这段代码几乎可以工作,除了它阻塞了我的[Excel.Worksheet] 类型规范。

正如this answer 指出的那样,我意识到没有必要指定参数类型,并且没有它,代码也可以正常工作。

但是为了取悦我内心的学究,有没有办法使用对 COM 对象类型(如Excel.Worksheet)的引用来限制参数类型?

    标签: excel powershell com


    【解决方案1】:

    PowerShell 抱怨您的 Excel.Worksheet 类型的原因是它不是真正的 .NET 类/接口的名称。

    您需要指定的参数类型是 Microsoft.Office.Interop.Excel.Worksheet (一旦加载了 Excel 互操作程序集,直接通过 Add-Type 或在调用 New-Object -ComObject Excel.Application 之后,因为这也会加载所需的库)

    话虽如此,我不相信这会按预期工作,因为 PowerShell 通过在 PowerShell 中公开的变量的真实类型之间创建透明的 COM 适配器层来处理 COM 对象的方式。

    有趣的是,PowerShell 在通过命名参数与位置参数提供参数转换时处理参数转换的方式似乎有所不同,如下面的演示代码所示:

    function Get-WorksheetName {
      param (
        [Parameter( Position = 1, Mandatory = $true )]
        [Microsoft.Office.Interop.Excel.Worksheet]
        $Worksheet
      )
    
      return $Worksheet.Name
    }
    

    使用命名参数调用函数失败:

    而通过位置参数调用函数按预期工作:

    如果您不想使用位置参数,那么另一种选择是删除参数类型约束,而是使用ValidateScript 属性检查类型。这仍然确保类型安全:

    function Get-WorksheetName {
      param (
        [Parameter(Position = 1, Mandatory = $true)]
        [ValidateScript({$_ -is [Microsoft.Office.Interop.Excel.Worksheet]})]
        $Worksheet
      )
    
      return $Worksheet.Name
    }
    

    传递不同类型的对象将导致:

    【讨论】:

    • 做得很好,特别是指出了命名参数绑定和位置参数绑定之间的区别:这可以说是一个错误,因为我之前在非 COM 上下文中看到过类似的问题,所以我创建了GitHub issue #17540
    猜你喜欢
    • 2013-10-10
    • 2019-11-04
    • 1970-01-01
    • 2020-03-24
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多