我正在尝试使用托管C#DLL(Managed.dll)中的非托管C ++ / ATL进程内COM对象(在Unmanaged.dll中)。但是,我希望我想使用免注册COM。我完成了以下步骤:
这会生成Unmanaged.dll,Managed.dll和Native.Managed.manifest。打开清单,很清楚系统如何使用它以免注册的方式加载COM对象。
这就是问题。我有一个托管EXE(Managed.exe),它动态加载Managed.dll以访问公共类型。我的意思是“动态”,它使用Assembly.LoadFrom(“Managed.dll”)。当Managed.dll内的代码尝试创建COM对象时,它会获得“未注册类”异常。当加载Managed.dll时,似乎无法正确设置激活上下文。
有没有办法让免注册COM在这种情况下工作?
答案 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。