我已经能够使用清单,特别是MSBuild任务GenerateApplicationManifest,以便我们的主应用程序使用隔离的COM。我可以创建所有在我需要的DLL中实现的COM对象,而无需在客户机上注册这些DLL。但是,我很贪心......通过准消费EXE服务器隔离COM
我们的应用程序套件也有一些独立的应用程序,通常通过COM调用。对于这些,据说你不能EXE来EXE隔离COM。严格地说,这是事实,但我已经获得了90%的道路,并且在其他论坛上我看到其他人提供了线索来获得剩余路线。
对于我的EXE服务器,我在清单中具有EXE服务器的名称和该条目中的子条目,以便当ATL服务器调用LoadRegTypeLib()
时,该调用将成功。这样可行。
当然,最棘手的部分是,你不能把在客户端应用程序清单的EXE服务器条目,并期待CoCreateInstance()
成功(通过启动服务器EXE和做所有其他的东西COM一样。)
因为我知道要启动的EXE服务器,所以我可以假装很多。我可以拨打CreateProcess()
,然后在客户端应用程序中拨打WaitForInputidle()
,以使我的服务器在客户端应用程序中可用于CoCreateInstance()。
如果我打电话CoCreateInstance()
并要求客户端应用程序中的IDispatch
界面,则调用成功,我可以调用Invoke()
并且一切正常。
现在,这里是贪婪的一部分...
这一切都很好这IDispatch的工作,但我希望能够通过我的IDispatch来自衍生双接口调用。我想这样做,因为我有很多用这种方式编写的代码,语法更简单,异常处理已经存在。
但是,当我在我的IDispatch
接口上拨打QueryInterface()
作为双接口时,我得到一个E_NOINTERFACE返回值。我在服务器EXE的ATL服务器对象中设置了断点,并可以确认在服务器端找到了接口并返回S_OK。所以,看起来不知何故界面不能被整理回客户端。
所以,问题是,我怎样才能得到QueryInterface()
为我的自定义/双接口成功?我试过在我的客户端清单(和服务器清单)中使用<comInterfaceProxyStub>
和<comInterfaceExternalProxyStub>
的各种组合尝试编组界面,但我仍然在客户端看到E_NOINTERFACE
返回。
几年前,我在一个不同的论坛上看到Hans Passant发表评论,可能需要一个单独的代理/存根DLL来编组接口,但没有太多细节。
它甚至有可能在无注册的上下文中解决这个问题吗?是否有必要创建一个代理/存根库?如果是这样,那么清单条目在我的客户端应用程序(和/或服务器应用程序和/或代理/存根DLL)中会是什么样子?
对于我的简单测试应用程序,我只有一个具有单一双界面的对象。在您的示例中,您具有(在内)和(在内)的元素。我需要每个条目之一吗?我使用ATL来生成带有PS DLL的EXE,有趣的是代理存根(通过检查注册表找到)的CLSID与接口的CLSID相同。 –
您只需使用其中一种方法。如果您的双接口使用标准编组(代理/存根DLL),请使用'comInterfaceProxyStub'。如果您的双接口使用类型库编组(TLB文件或嵌入在DLL资源中)或任何其他注册(非隔离)代理/存根,请使用'comInterfaceExternalProxyStub'。我将用两个单独的例子编辑答案以反映这一点。 – acelent
由于您提到代理/存根的CLSID与IID相同,(最可能)它必须是您使用标准编组的情况,因此您有一个代理/存根DLL。使用'comInterfaceProxyStub'。 – acelent