PowerShell中的New-Object -ComObject和VB中的CreateObject()有什么区别?

5

我有一个关于Windows PowerShell在处理Com互操作时的工作方式的问题。

我有一个第三方应用程序(让我们称其为ThirdPartyApp),它公开了一个可以调用的API。

我可以在例如Excel或Visual Studio中进行早期绑定,直接与其交互。 我可以在VBScript中进行晚期绑定,并仍然可以“直接”与其交互。

所谓“直接”,是指使用类似于ThirdPartyApp.Name的语法调用API公开的属性和方法的方式。

因此,在VBScript中,我可以执行以下操作:

Dim api : Set api = CreateObject("ThirdPartyApp.API")
WScript.Echo api.Name

在PowerShell中,当我执行以下操作:
$api =  New-Object -ComObject ThirdPartyApp.API

我必须使用这个语法来获取名称:

[System.__ComObject].InvokeMember('Name',[System.Reflection.BindingFlags]::GetProperty,$null,$api,$null)

现在,我明白这与 ThirdPartyApp 的构建方式有关。

我知道这不是一个编码问题,希望不会被立即踩,但我的问题是:为什么当使用 Powershell 时我不能以 VBScript 的方式访问该程序集?在 Powershell 中 New-Object -ComObject 和 VBScript 中的 CreateObject(identifier) 有何区别?


请更新问题以澄清您是否正在使用Windows PowerShell或PowerShell [Core]。 - mklement0
完成。这是关于Windows Powershell的内容。它涉及到COM,这只适用于Windows系统,对吧?但没关系。 - Rno
感谢您的澄清。PowerShell [Core] 也可以在 Windows 上运行,但其 COM 支持在某些方面存在缺陷,因此我才提出了这个问题。根据标签“powershell”的指导,应该暗示使用 Windows PowerShell - 对于 PowerShell [Core] 的问题,建议使用“powershell-core”标签,但我怀疑随着 PowerShell [Core] 的普及,这条线将越来越模糊。 - mklement0
1个回答

0

面向Visual Basic程序员的信息

Visual Basic提供了完整的自动化支持。以下表格列出了Visual Basic语句如何转换为OLE API。

Visual Basic语句 OLE APIs

CreateObject (“ProgID”)

  • CLSIDFromProgID

  • CoCreateInstance

  • 查询接口以获取IDispatch接口。

GetObject (“filename”, “ProgID”)

  • CLSIDFromProgID

  • CoCreateInstance

  • 查询接口以获取IPersistFile接口。

  • 在IPersistFile接口上加载。

  • 查询接口以获取IDispatch接口。

GetObject (“filename”)\

  • CreateBindCtx 创建绑定上下文以供随后的函数使用。

  • MkParseDisplayName 返回一个用于 BindMoniker 的单体句柄。

  • BindMoniker 返回一个指向 IDispatch 接口的指针。

  • 释放单体句柄。

  • 释放上下文。

GetObject(“ProgID”)

  • CLSIDFromProgID

  • 在类 ID 上调用 GetActiveObject。

  • QueryInterface 以获取 IDispatch 接口。

Dim x As New interface

  • 查找接口的 CLSID。

  • CoCreateInstance

  • QueryInterface

MSDN Library 2001 年 10 月 Microsoft Corp.

请参阅 https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/


谢谢您提供的信息,但那并没有涉及到 PowerShell 部分。 - Rno
因为我想了解它们之间的区别,所以使用了这两个标签。 - Rno
我感谢你的帮助。但仍有一个问题困扰着我,那就是如果在VB中使用“QueryInterface获取IDispatch接口”足以启用对该接口成员的“直接”调用,为什么我有时(取决于应用程序)必须在PowerShell中使用相当复杂的语法呢? - Rno
也许你的问题是一个.NET问题,PowerShell使用它。.NET将COM类封装在.NET类中,反之亦然。对于BASIC程序员来说,没有区别。在任何MS Basic中相同或类似的代码,如VB.NET更严格,都可以完全相同地工作。也许你应该问PowerShell的人如何实现调用-这是一个高级而复杂的主题,我不会发表意见。 - user12431753

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接