【问题标题】:Looking up the value for MS Office Interop constants rather than hard coding them查找 MS Office 互操作常量的值,而不是对其进行硬编码
【发布时间】:2011-05-15 09:57:54
【问题描述】:

使用 PowerShell,创建 Excel 应用程序类的实例并开始操作它很容易:

$app = New-Object -ComObject "Excel.Application"

但是,如果我需要使用诸如 xlDoubleQuote 或 xlDelimited 之类的常量 - 似乎我不得不对它们进行硬编码。我真的很想能够做这样的事情:

$constants = New-Object -ComObject "Excel.Constants"
$constants.xlDoubleQuote

并且看到它会返回值 1。不幸的是,我无法创建枚举的实例,而且似乎没有像普通 .NET 类库那样引用它的方法:

[Excel.Constants]::xlDoubleQuote

有没有办法将该枚举动态导入 PowerShell?也许通过托管库而不是 COM?

【问题讨论】:

    标签: com powershell ms-office office-interop


    【解决方案1】:

    使用 Excel 的主互操作程序集。如果你安装了 Office,这些应该在 GAC 中。像这样使用:

    Add-Type -AssemblyName Microsoft.Office.Interop.Excel
    [int][Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote
    

    【讨论】:

    • 或:[Microsoft.Office.Interop.Excel.Constants]::xlDoubleQuote.Value__
    • 这是最好的,但似乎 Visio 的处理方式不同。下面的另一个答案中描述了一种勉强可接受的解决方法(填充哈希大约需要 12 秒)。
    【解决方案2】:

    Keith 已经给你答案了,这里还有一个选项。您可以在 $xlConstants 对象上使用制表符完成来获取常量:

    $xl = New-Object -ComObject Excel.Application
    $constants = $xl.gettype().assembly.getexportedtypes() | where-object {$_.IsEnum -and $_.name -eq 'constants'}
    
    $pso = new-object psobject
    [enum]::getNames($constants) | foreach { $pso | Add-Member -MemberType NoteProperty $_ ($constants::$_) }
    $xlConstants = $pso
    

    【讨论】:

      【解决方案3】:

      Keith 和 Shay 给出了完美的答案,但是请注意:

      使用 Excel 2003 或 Excel 2007 时,应在计算机上安装 Office 主互操作程序集 (PIA)。 Microsoft 提供了可再发行版本。有关更多信息,请参阅此处发布的 stackoverflow.com:

      Different Interop references on two different computers doesn't work

      【讨论】:

        【解决方案4】:

        使用 Visio 2016 32 位,我发现尝试使用 Keith Hill 的方法会导致错误消息:“添加类型:无法添加类型。找不到程序集 'Microsoft.Office.Interop.Visio'。” Shay Levy 的方法需要更多修改才能与 Visio 一起使用。这是我能够得到的工作:

        $visioApp = New-Object -ComObject Visio.Application 
        $visioConstants = @{}
        
        $visioEnums = $visioApp.gettype().assembly.getexportedtypes() | where-object {$_.IsEnum } #-and $_.name -eq 'constants'}
        
        The answers of Keith Hill and Shay Levy are best, however, I found that Visio 
        $visioEnums |%{
            $enumname = $_
            [enum]::getNames($enumname) | foreach {
                $val = invoke-expression "[$($enumname)]::$($_).value__"
                $visConstants.$_ = $val
            }
        }
        $visioApp.Quit()
        
        echo $visConstants.visTopEdge 
        

        令人失望的是,在我测试时执行大约需要 12 秒。

        【讨论】:

          【解决方案5】:

          Keith Hill's helpful answer 的技术与Shay Levy's answer 的制表符补全理念结合起来:

          # Instantiate Excel, which implicitly loads the interop
          # assembly that contains the [enum] type of interest.
          # Assign to $null, if you're not planning on using the object further.
          $xl = New-Object -ComObject Excel.Application
          
          # Store the [enum] type of interest in a variable for easier access.
          $xlConstants = [Microsoft.Office.Interop.Excel.Constants]
          

          注意:要查找Constants类型的全名,可以使用制表符补全:运行New-Object -ComObject Excel.Application后,键入[constants<tab>(不要键入结束]),它应该扩展为[Microsoft.Office.Interop.Excel.Constants;如果出现了来自命名空间其他而不是Microsoft.Office.Interop.Excel 的类型,请按 Tab 键直到找到所需的类型。

          现在你可以:

          • 通过:: 运算符,将单个枚举值作为存储在$xlConstants 中的类型的静态成员访问,该运算符也适用于制表符补全;例如:

            $xlConstants::xl3d<tab>  # -> expands to $xlConstants::xl3DBar
            
          • 通过转换为[int] 或访问.Value__ 属性来获取特定值的基础数字:

            [int] $xlConstants::xl3DBar    # -> -4099
            
            $xlConstants::xl3DBar.Value__  # ditto
            
          • 枚举所有符号名:

            [enum]::GetNames($xlConstants)
            
          • 同时显示符号名称背后的数字:

            PS> [enum]::GetNames($xlConstants) |
                Select @{ n='Name'; e={$_} }, @{ n='Number'; e={ $xlConstants::$_.Value__ } }
            
            Name            Number
            ----            ------
            xlAbove              0
            xlFirst              0
            xlDirect             1
            # ...
            

          【讨论】:

            猜你喜欢
            • 2021-03-28
            • 1970-01-01
            • 1970-01-01
            • 2022-10-13
            • 1970-01-01
            • 1970-01-01
            • 2021-09-12
            • 1970-01-01
            • 2020-01-27
            相关资源
            最近更新 更多