VBA-具有依赖项的.net dll ActiveX Cant创建对象

时间:2019-01-07 21:44:52

标签: .net vba dll com activex

我已经编写了一个.Net库,其中封装了一些需要与旧系统交互的业务逻辑。该库的目的是公开一个COM接口,以便我可以使用VBA从Office应用程序中调用它。

我已经完成了使用带有/ codebase / tlb标志的64位Regasm.exe进行注册所需的一切。它在我的Office应用程序中可见,甚至以智能感知显示。但是,我一直收到“ ActiveX组件无法创建对象”错误。

为了尝试确定我的COM接口的设置/配置中是否存在错误,我创建了一个独立的.Net库作为解决方案的一部分,其中仅提供了一个基本类和方法来返回“ Hellow World”。这实际上可以按预期工作,即我在VBA应用程序的“引用”对话框中注册了它,并可以实例化它并运行“ HelloWorld”方法。

Dim simple as SimpleInterface.MyClass
Set simple = New SimpleInterface.MyClass

MsgBox simple.HelloWorld("Say Hello")

然后,我在新的基本VS项目中对所需项目(业务逻辑)进行引用,并在此处调用一个方法,然后在我的简单项目中创建另一个方法以公开为COM接口。我注销dll并按照上述方法进行注册。

然后在我的VBA应用程序中取消选择.tlb文件,将其关闭再重新打开,然后重新引用它,然后尝试运行代码。这是当我收到“ ActiveX组件无法创建对象”时。我假设这与我项目中的依赖dll有关,但我不确定,因为该错误的详细信息很少。

我不确定我应该在这里做什么?我是否需要重新注册所有其他依赖的dll,即我在VS项目中仅引用了大约2或3个外部dll?有人可以告诉我如何找到更多进一步的细节,即确切的违规dll吗?

1 个答案:

答案 0 :(得分:2)

“ ActiveX组件无法创建对象”错误通常意味着定位程序集或其依赖项之一时出现问题,或者程序集不包含带有所请求ProgID的任何公共类。要获取有关程序集加载故障排除的更多详细信息,建议使用Assembly Binding Log Viewer

要检查的一些事情

  • 那么您实际上正在使用MS Office的64位版本? (由于64位和32位版本在Excel文件之类的文件格式/限制方面不兼容,我一直认为32位版本仍是最常用的版本。不再是这种情况吗...?)
  • 编译Visual Studio项目时,您选择了哪个目标平台?
  • 是否已在项目设置中选中“注册COM Interop”复选框来编译项目?

我在这里得到的是:您是否有任何种可能性,实际上是在为错误的平台/位数构建/注册(即,与您的MS Office安装的位数不匹配) )?是否可以使用旧的注册来获取正确的位数,这也许可以解释为什么尽管为错误的目标平台进行了构建,但为什么您仍然在VBA IDE的“引用”对话框中看到类型库?

通过COM互操作公开.NET类时要记住的另一件大事

默认情况下,每次编译项目时,Visual Studio都会为暴露的类生成新的随机ProgID GUIDs 。这就是为什么您必须麻烦删除引用,然后在VBA IDE中再次添加它们,以使事情在重新编译.NET项目之后又能正常工作的原因。

不仅如此,除非您确保在使用新编译的版本覆盖程序集之前始终注销(RegAsm /u /tlb)程序集,否则它还会用很多过时的键使注册表混乱。

为避免这些情况,您应该在.NET代码中COM公开类上使用ProgID attributes来显式设置ProgID GUID。还建议使用ComVisible attribute,并在程序集级别将其设置为false,仅在需要向COM公开的类型上才将其显式设置为true。

关于.NET依赖项

您只需注册包含指向组件的“入口”的DLL,即您从VBA调用的方法。但是,.NET运行时需要能够找到依赖关系,就像对任何类型的.NET程序集一样。这通常是通过将依赖项的副本与入口点DLL保留在同一文件夹中来实现的。默认情况下,Visual Studio通常将程序集/项目引用的依赖关系复制到输出文件夹,GAC中存在的程序集除外。

如何使用Visual Studio调试器

通过将Visual Studio调试器附加到正在运行的excel.exe进程(菜单中的Debug > Attach to Process),可以在从VBA调用.NET代码时对其进行调试。确保在Excel进程的“类型”列中提到“托管”,并且确保调试器将附加到此(除非您弄乱了设置,否则该调试器将自动发生)。

如果未在Excel流程中提及“托管”,则表明Excel尚未加载程序集;尝试在创建COM对象的语句之后立即使用带有断点的VBA代码,然后尝试再次附加调试器。

连接Visual Studio调试器后,您将可以访问有关发生的事情的更多信息。这样,只要引发.NET异常,您就可以使VS调试器中断,还可以添加断点并逐步执行.NET代码。如果您还没有的话,真的很值得研究。