简体   繁体   English

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

[英]VBA - ActiveX Cant Create Object for .net dll with dependencies

I have written a .Net library which encapsulates some of my business logic that needs to interact with a legacy system. 我已经编写了一个.Net库,其中封装了一些需要与旧系统交互的业务逻辑。 The purpose of this library is to expose a COM interface so that I can call it from Office Applications using VBA. 该库的目的是公开COM接口,以便我可以使用VBA从Office应用程序中调用它。

I've done everything I need to do to get it registered using 64bit Regasm.exe with /codebase /tlb flags. 我已经做了所有需要做的事情,以使用带有/ codebase / tlb标志的64位Regasm.exe进行注册。 It is visible in my Office Applications and is even showing in intellisense. 它在我的Office应用程序中可见,甚至以智能感知显示。 However, I keep getting the "ActiveX Component cant create object" error. 但是,我一直收到“ ActiveX组件无法创建对象”错误。

To try and determine if there was an error in my setup/configuration of the COM interface I created a sepearte .Net library as part of my solution with just a basic class and method to return a "Hellow World". 为了尝试确定我的COM接口设置/配置中是否存在错误,我创建了一个独立的.Net库作为解决方案的一部分,其中仅提供了一个基本类和方法来返回“ Hellow World”。 This actually works as expected ie I register it in the References dialog in the VBA application and can instantiate it and run the "HelloWorld" method. 这实际上可以按预期工作,即我在VBA应用程序的“引用”对话框中注册了它,并可以实例化它并运行“ HelloWorld”方法。

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

MsgBox simple.HelloWorld("Say Hello")

Then I make a reference in my new basic VS project to my desired project (business logic) and make a call to one method in here and then make another method in my simple project to expose as a COM interface. 然后,在新的基本VS项目中,对所需的项目(业务逻辑)进行引用,并在此处调用一个方法,然后在我的简单项目中创建另一个方法,以公开为COM接口。 I unregister the dll and register as in the method above. 我注销dll并按照上述方法进行注册。

In my VBA application I then unselect the .tlb file close it down re-open it and then re-reference it and then try and run the code. 然后,在我的VBA应用程序中,取消选择.tlb文件,将其关闭,然后重新打开,然后重新引用它,然后尝试运行代码。 This is when I get the "ActiveX componenent can't create object". 这是当我收到“ ActiveX组件无法创建对象”时。 I'm assuming this has somethingn to do with dependent dlls in my project but Im unsure as there is very little details with the error. 我假设这与我项目中的依赖dll有关,但我不确定,因为该错误的细节很少。

I'm not sure what I am supposed to do here? 我不确定在这里应该做什么? Do I need to regsiter all other dependent dlls ie I have about 2 or 3 external dll's which I just make a reference to in the VS project? 我是否需要重新注册所有其他依赖的dll,即我在VS项目中仅引用了大约2或3个外部dll? CAn someone tell me how it is possible to find any more futher detail ie which is the exact offending dll? 有人可以告诉我如何找到更多详细信息,即确切的违规dll是什么?

The "ActiveX Component can't create object" error usually means that there was a problem locating the assembly or one of its dependencies, or that the assembly does not contain any public class with the requested ProgID. “ ActiveX组件无法创建对象”错误通常意味着在查找程序集或其依赖项之一时出现问题,或者该程序集不包含带有所请求ProgID的任何公共类。 To get more details for troubleshooting assembly loading, I would suggest using the Assembly Binding Log Viewer . 要获取有关对程序集加载进行故障排除的更多详细信息,建议使用Assembly Binding Log Viewer

Some things to check 一些要检查的东西

  • So you're actually using 64-bit edition of MS Office? 那么您实际上正在使用MS Office的64位版本? (I've been under the impression that the 32-bit edition is still the most commonly used one, due to incompatibility between the 64-bit and 32-bit editions regarding file formats/limitations for things like Excel documents, but maybe this isn't the case any more...?) (由于64位和32位版本在Excel文件之类的文件格式/限制方面不兼容,我一直认为32位版本仍是最常用的版本。不再是这种情况...?)
  • What target platform have you selected when you compile the Visual Studio project? 编译Visual Studio项目时,选择了什么目标平台?
  • Has the project ever been compiled with the checkbox "Register for COM Interop" checked in the project settings? 是否在项目设置中选中了“注册COM Interop”复选框来编译项目?

What I'm getting at here is this: Is there any possibility that you're actually building/registering for the wrong platform/bitness (ie, not matching the bitness of your MS Office installation)? 什么我得到在这里是这样的:有没有你实际上建立/注册的错误的平台/位数(即不匹配您的MS Office安装的位数) 可能性? Could there be an old registration for the correct bitness, which might explain why you still see the Type Library in the References dialog of the VBA IDE, despite building for the wrong target platform? 可能会有一个旧的注册来证明正确的位数,这也许可以解释为什么尽管构建了错误的目标平台,但在VBA IDE的“引用”对话框中仍然看到类型库?

One other big thing to keep in mind when exposing .NET classes through COM interop 通过COM互操作公开.NET类时要记住的另一件大事

By default, Visual Studio will generate new random ProgID GUIDs for your exposed classes every time you compile the project . 默认情况下, 每次编译项目时 ,Visual Studio都会为暴露的类生成新的随机ProgID GUID This is why you have to go through the trouble of removing references and then adding them back again in the VBA IDE to make things work again after re-compiling your .NET project. 这就是为什么您必须麻烦删除引用,然后在VBA IDE中再次添加它们,以使事情在重新编译.NET项目之后又能正常工作的原因。

Not only that, but it also clutters up the registry with lots of obsolete keys unless you make sure to always unregister ( RegAsm /u /tlb ) your assembly before overwriting it with a newly compiled version. 不仅如此,除非您确保在使用新编译的版本覆盖程序集之前始终取消注册( RegAsm /u /tlb ),否则它还会用很多过时的键使注册表RegAsm /u /tlb

To prevent these things, you should explicitly set the ProgID GUIDs using ProgID attributes on the COM-exposed classes in your .NET code. 为避免这些情况,您应使用.NET代码中COM公开类上的ProgID属性显式设置ProgID GUID。 It is also recommended to use the ComVisible attribute , and have it set to false on assembly level, and explicitly set to true only on those types that need to be exposed to COM. 还建议使用ComVisible属性 ,并在程序集级别将其设置为false,仅在需要向COM公开的那些类型上将其显式设置为true。

Regarding .NET dependencies 关于.NET依赖项

You only have to register the DLL that contains the "entry point" to your component, ie the method you're calling from VBA. 您只需要注册包含指向组件的“入口”的DLL,即您从VBA调用的方法。 The .NET runtime needs to be able to find the dependencies, though, just like it does for any type of .NET assembly. 但是,.NET运行时需要能够找到依赖关系,就像对任何类型的.NET程序集一样。 This is usually achieved by keeping copies of the dependencies in the same folder as the entry point DLL. 这通常是通过将依赖项的副本与入口点DLL保留在同一文件夹中来实现的。 Visual Studio usually copies dependencies to the output folder by default for assembly/project references, except for assemblies that exist in the GAC. 默认情况下,Visual Studio通常将程序集/项目引用的依赖关系复制到输出文件夹,GAC中存在的程序集除外。

How to use the Visual Studio debugger 如何使用Visual Studio调试器

You can debug your .NET code while it is being called from VBA by attaching the Visual Studio debugger to the running excel.exe process ( Debug > Attach to Process from the menus). 通过将Visual Studio调试器Debug > Attach to Process正在运行的excel.exe进程(从菜单中的“ Debug > Attach to Process ”),可以在从VBA调用.NET代码时对其进行Debug > Attach to Process Make sure that "Managed" is mentioned in the Type column for the Excel process, and that that the debugger will attach to that (should happen automatically, unless you've fiddled with the settings). 确保在Excel进程的“类型”列中提到“托管”,并且确保调试器将附加到此(除非您弄乱了设置,否则该调试器将自动发生)。

If "Managed" isn't mentioned for the Excel process, it means that Excel hasn't loaded your assembly yet; 如果未在Excel流程中提及“托管”,则表示Excel尚未加载程序集; try running the VBA code with a breakpoint right after the statement that creates the COM object, then try attaching the debugger again. 尝试在创建COM对象的语句之后立即使用带有断点的VBA代码,然后尝试再次附加调试器。

After you have attached the Visual Studio debugger, you will have access to a lot more information about what is going on. 附加Visual Studio调试器后,您将可以访问有关发生的事情的更多信息。 You will then be able to have the VS debugger break whenever a .NET exception is thrown, and you can also add breakpoints and step through the .NET code. 这样,只要引发.NET异常,您就可以使VS调试器中断,还可以添加断点并逐步执行.NET代码。 Really worth looking into, if you haven't already. 如果您还没有的话,真的很值得研究。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM