问题描述
我有一个关于 Windows PowerShell 在处理 Com Interop 时如何工作的问题.
我有一个 3rd 方应用程序(我们称之为 ThirdPartyApp
),它公开了一个我可以调用的 API.
我可以在例如早期绑定它Excel 或 Visual Studio 并直接"与之对话.我可以在 VBScript 中后期绑定它,并且仍然可以直接"与它对话.
直接"是指我可以使用类似 ThirdPartyApp.Name
所以在 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)
有何不同?
Visual Basic 程序员信息
Visual Basic 完全支持自动化.下表列出了 Visual Basic 语句如何转换为 OLE API.
Visual Basic 语句 OLE API
创建对象(ProgID")
CLSIDFromProgID
CoCreateInstance
QueryInterface 获取 IDispatch 接口.
GetObject(文件名"、ProgID")
CLSIDFromProgID
CoCreateInstance
IPersistFile 接口的查询接口.
在 IPersistFile 接口上加载.
QueryInterface 获取 IDispatch 接口.
GetObject(文件名")\
CreateBindCtx 为后续函数创建绑定上下文.
MkParseDisplayName 返回 BindMoniker 的名字对象句柄.
BindMoniker 返回一个指向 IDispatch 接口的指针.
释放名字句柄.
根据上下文发布.
GetObject(ProgID")
CLSIDFromProgID
在类 ID 上获取活动对象.
QueryInterface 获取 IDispatch 接口.
Dim x As New 界面
查找接口的 CLSID.
CoCreateInstance
查询接口
微软公司 2001 年 10 月 MSDN 库
请参阅 https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/
I have a question about how Windows PowerShell works when dealing with Com Interop.
I have a 3rd party application (let's call it ThirdPartyApp
) that exposes an API that I can call into.
I can early-bind it in e.g. Excel or Visual Studio and talk to it 'directly'. I can late-bind it in VBScript and still talk to it 'directly'.
By 'directly' I mean the way I can call properties and methods exposed by the API using syntax like ThirdPartyApp.Name
So in VBScript I can do:
Dim api : Set api = CreateObject("ThirdPartyApp.API")
WScript.Echo api.Name
In PowerShell, when I do:
$api = New-Object -ComObject ThirdPartyApp.API
I have to use this syntax to get the Name:
[System.__ComObject].InvokeMember('Name',[System.Reflection.BindingFlags]::GetProperty,$null,$api,$null)
Now, I understand that that has something to do with how ThirdPartyApp
was built.
I know this isn't a coding problem, and I hope I don't get downvoted immediately, but my question is: why can't I talk to this assembly the VBScript way when using Powershell? How does New-Object -ComObject
in Powershell differ from CreateObject(identifier)
in VBScript?
Information for Visual Basic Programmers
Visual Basic provides full support for Automation. The following table lists how Visual Basic statements translate into OLE APIs.
Visual Basic statement OLE APIs
CreateObject ("ProgID")
CLSIDFromProgID
CoCreateInstance
QueryInterface to get IDispatch interface.
GetObject ("filename", "ProgID")
CLSIDFromProgID
CoCreateInstance
QueryInterface for IPersistFile interface.
Load on IPersistFile interface.
QueryInterface to get IDispatch interface.
GetObject ("filename")\
CreateBindCtx creates the bind context for the subsequent functions.
MkParseDisplayName returns a moniker handle for BindMoniker.
BindMoniker returns a pointer to the IDispatch interface.
Release on moniker handle.
Release on context.
GetObject ("ProgID")
CLSIDFromProgID
GetActiveObject on class ID.
QueryInterface to get IDispatch interface.
Dim x As New interface
Find CLSID for interface.
CoCreateInstance
QueryInterface
MSDN Library October 2001 Microsoft Corp.
See https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/
这篇关于Powershell 中的 New-Object -ComObject 和 VB 中的 CreateObject() 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!