如何在托管/非托管互操作中获得免注册COM

时间:2011-03-22 13:37:33

标签: com-interop regfreecom

我正在尝试使用托管C#DLL(Managed.dll)中的非托管C ++ / ATL进程内COM对象(在Unmanaged.dll中)。但是,我希望我想使用免注册COM。我完成了以下步骤:

  • 在开发计算机上注册COM对象。进程内服务器必须具有正确注册的类型库。
  • 在C#项目中添加对COM对象的引用,然后将Reference Properties设置为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在这种情况下工作?

1 个答案:

答案 0 :(得分:2)

两天没有答案,所以这就是我在那个时候提出来的......

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

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

我用一个托管类来包装这些调用,该类在构造函数中调用CreateActCtx和ActivationActCtx,在IDisposable :: Dispose中调用DeativateActCtx和ReleaseActCtx。