我有一个非托管的C ++ / ATL进程内COM对象(位于Unmanaged.dll中),该对象正试图从托管的C#DLL(Managed.dll)中使用。但是,我想使用免费注册的COM。我将其归结为以下步骤:

  • 在开发机器上注册COM对象。进程内服务器必须具有正确注册的类型库。
  • 在C#项目中添加对COM对象的引用,然后将“引用属性”设置为Isolated= True。

    这将生成Unmanaged.dll,Managed.dll和Native.Managed.manifest。打开清单,很明显系统是如何使用它以免注册的方式加载COM对象的。

    这是磨擦。我有一个托管EXE(Managed.exe),可以动态加载Managed.dll来访问公共类型。我所说的“动态地”是,它使用Assembly.LoadFrom(“ Managed.dll”)。当Managed.dll中的代码尝试创建COM对象时,它将收到“未注册类”异常。加载Managed.dll时,似乎激活上下文未正确设置。

    有没有一种方法可以使免费注册的COM在这种情况下工作?

有帮助吗?

解决方案

两天没有答案,所以这就是我当时的想法...

确实看起来激活上下文是由操作系统在启动时基于与主EXE关联的清单设置的。这意味着在启动过程时,所有与注册无关的COM相关元素都必须位于Main.exe.manifest中。这打破了EXE和DLL之间的隔离。如果DLL负责创建COM对象,则您不会期望EXE清单必须包含无reg的COM信息。您可能已经期望与DLL相关联的清单在DLL加载时会合并到进程激活上下文中,但事实并非如此。

要变通解决此问题,DLL必须在创建COM对象之前配置一个新的激活上下文。更糟的是,目前(从.NET 4.0开始)没有托管的方式可以做到这一点。因此,DLL将必须P调用以下Win32函数:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top