Visual Basic-调用.net运行时
我正在尝试从VBA(Word/Excel)调用.net运行时中的对象。 这项工作:Visual Basic-调用.net运行时,.net,vba,excel,com,.net,Vba,Excel,Com,我正在尝试从VBA(Word/Excel)调用.net运行时中的对象。 这项工作: oT=CreateObject(“System.Text.UTF8Encoding”) 但不是这个: CreateObject(“System.Management.Automation.Runspaces.RunspaceFactory”) 错误是: 运行时错误'429';ActiveX组件无法创建对象 我不明白的是Excel/Word如何确定哪些类是公开的,哪些不是调用CreateObject时指定的
oT=CreateObject(“System.Text.UTF8Encoding”)
但不是这个:
CreateObject(“System.Management.Automation.Runspaces.RunspaceFactory”)
错误是:
运行时错误'429';ActiveX组件无法创建对象
我不明白的是Excel/Word如何确定哪些类是公开的,哪些不是调用
CreateObject
时指定的参数不是名称空间,而是一个ProgId
——COM用来定位已注册类(以及它们在其中定义的库以及该库所在的库)的字符串,在Windows注册表中
如果没有注册的COM类型的ProgId
值为System.Management.Automation.Runspaces.RunspaceFactory
,则ActiveX无法创建该对象
如果命名空间没有COM类型库(即程序集未注册COM互操作),那么您正试图让COM理解.NET/托管代码,而这是无法做到的
我不明白的是Excel/Word如何确定哪些类是公开的,哪些不是
Excel/Word/任何与之无关的主机应用程序,都是VBA自己的运行时加载COM类型,是Windows注册表包含注册的所有内容的ProgId
如果在注册表中的
HKEY\U LOCAL\U MACHINE\SOFTWARE\Classes\CLSID
下搜索Scripting.Dictionary
,最终会找到一个名为{EE09B103-97E0-11CF-978F-00A02463E06F}
,,使用值为Scripting.Dictionary
的ProgID子项和值为C:\Windows\system32\scrrun.dll
的InprocServer32
子项,并且如果VBA运行时在该类型库中成功创建具有指定ProgID
的类型实例,然后,CreateObject
调用成功并返回实例。否则,它会抛出一个错误429并显示“ActiveX无法创建对象”。调用CreateObject
时指定的参数不是命名空间,而是一个ProgId
—COM用于在Windows注册表中定位已注册类(以及它们在其中定义的库以及该库所在的位置)的字符串
如果没有注册的COM类型的ProgId
值为System.Management.Automation.Runspaces.RunspaceFactory
,则ActiveX无法创建该对象
如果命名空间没有COM类型库(即程序集未注册COM互操作),那么您正试图让COM理解.NET/托管代码,而这是无法做到的
我不明白的是Excel/Word如何确定哪些类是公开的,哪些不是
Excel/Word/任何与之无关的主机应用程序,都是VBA自己的运行时加载COM类型,是Windows注册表包含注册的所有内容的ProgId
如果在注册表中的HKEY\U LOCAL\U MACHINE\SOFTWARE\Classes\CLSID
下搜索Scripting.Dictionary
,最终会找到一个名为{EE09B103-97E0-11CF-978F-00A02463E06F}
,,使用值为Scripting.Dictionary
的ProgID子项和值为C:\Windows\system32\scrrun.dll
的InprocServer32
子项,并且如果VBA运行时在该类型库中成功创建具有指定ProgID
的类型实例,然后,CreateObject
调用成功并返回实例。否则,它会抛出一个错误429,并说“ActiveX无法创建对象”。Simple:Excel/Word甚至不会远程介入。这是VBE的工作,而不是宿主应用程序的。那么VBE如何知道哪些是可访问的,哪些不是?只有.NET类的子集是[ComVisible(true)]。主要是.NET1.0中的内容,当时仍然很重要的是让程序员跟上.NET的潮流,而不是强迫他们重写他们拥有的一切。你必须创建你自己的[ComVisible]包装器。@HansPassant我的答案是作为一个有根据的猜测写的(在Ruberduck中玩弄COM互操作已经有几年了),如果你能让我知道我的猜测是否正确,我会很高兴的(见鬼,如果你想偷那个复选标记的话)!很好,对不起,忘了紫外线。很简单:Excel/Word根本不参与其中。这是VBE的工作,而不是宿主应用程序的。那么VBE如何知道哪些是可访问的,哪些不是?只有.NET类的子集是[ComVisible(true)]。主要是.NET1.0中的内容,当时仍然很重要的是让程序员跟上.NET的潮流,而不是强迫他们重写他们拥有的一切。你必须创建你自己的[ComVisible]包装器。@HansPassant我的答案是作为一个有根据的猜测写的(在Ruberduck中玩弄COM互操作已经有几年了),如果你能让我知道我的猜测是否正确,我会很高兴的(见鬼,如果你想偷那个复选标记的话)!很好,忘了UV,抱歉。FWIW-ProgId
对于CreateObject
不是严格要求的-可以使用CLSID代替它,这在符合COM的对象没有ProgId
的情况下很有用。一个很好的例子是MS Forms 2.0库中的MSForms.DataObject
,它缺少ProgID
:Set-objData=CreateObject(“新:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}”)FWIW-ProgId
对于CreateObject
不是严格要求的-可以使用CLSID代替它,这在符合COM的对象没有ProgId
的某些情况下非常有用。一个很好的例子是MS Forms 2.0库中的MSForms.DataObject
,它缺少ProgID
:Set-objData=CreateObject(“新:{1C3B4210-F441-11CE-B9EA-00AA006