2010-01-14 19 views
3

我们正在调整我们的客户端相对复杂的应用程序(ActiveX/.net/Delphi/C++/COM)以使用SxS实现非管理部署并与我们的产品的旧版本隔离。模拟SideBySide用于不在线ActiveX

我们几乎所有的proc组件都可以实现这个目标,比如我们的.net ui,Delphi ui和我们在proc中使用的COM服务器,通过组合一个清单文件来描述我们的进程使用的所有库,没有任何组件的客户注册(几乎)。

这里来的几乎是: 目前,我们的应用程序调用(从它的C++部分)一个超过ActiveX的ActiveX服务器(Delphi ActiveX EXE),它本身又调用另一组超出proc的ActiveX服务器(第三方插件,任何东西都在这里,Delphi,C++,只要它没有执行ActiveX EXE并实现我们的接口)。

As we know SxS不支持proc ActiveX服务器。而且我们不能像我们主流程中的proc com服务器那样使用这些对象,因为这需要对我们的应用程序进行重大改写,甚至是最坏的情况,第三方工具和供应商使用的面向公众的API的中断,api我们不能允许的休息。

我们偶然发现了this article,它描述了如何从单独的进程中运行的Internet Explorer窗口中提取IHTMLDocument2。这使我们想到了这种方法:

我们将创建一个辅助卫星应用程序/进程,它将在进程服务器中运行ActiveX。 然后,我们将使用LresultFromObjectObjectFromLresult将ActiveX对象的引用从卫星应用程序传输到主应用程序进程。卫星应用程序将拥有自己的清单文件,这将允许它以SxS模式运行。

同样的方法将采取这种德尔福的ActiveX EXE和第三方AciveX EXE插件

有一个替代的解决方案,这对于目前我们还没有结束提出的解决方案更喜欢上面是使用之间的通信.net远程处理和.net com代理类来打开两个进程之间的通信通道,将com请求转换为.net远程处理,并在第二个进程中返回com。

所以问题来了:

  1. ,你怎么看待这种做法?
  2. 您是否看到更好的解决方案?

回答

4

这是可能的。需要什么:

  • 一个应用程序需要启动一个服务器本身,而不是依靠COM去做。您不需要注册表提供的额外间接寻址,只需使用CreateProcess()即可。
  • 服务器应该使用CoRegisterClassObject()在它的main()方法中注册它的类工厂。
  • 重要提示:对于每个服务实例,它应该将每个工厂使用的CLSID更改为唯一。这可确保客户端连接到正确的服务器。我只是用一个类工厂CLSID X进程ID。客户端也知道进程ID,因此可以进行相同的更改。
  • 应用程序应该在带有Sleep()调用的循环中调用CoCreateInstance()以等待对象工厂出现。不要宣布失败,直到至少60秒过去(那我)。
  • 应用程序和服务器都需要一个清单,其中包含每个代理/存根DLL的<file>元素和远程每个接口的<comInterfaceExternProxyStub>元素。
+0

纠正我,如果我错了,但你的提议不使用ObjectFromLresult,因为我已经建议对吗? 关于CoRegisterClassObject,它到底在哪注册它,如果它没有在注册表中注册,即使它在清单中,我的应用程序如何能够使用CoCreateInstance找到它? – 2010-01-16 21:00:34

+0

它没有。 CoCreateInstance()会在运行的对象表中找到它。 – 2010-01-16 22:25:01

+0

非常感谢,如果不是为了您的帮助,它会让我很年轻。 – 2010-01-20 11:58:52

0

亚历克斯,

nobugz是正确的,你可以访问运行对象表从你的Delphi自动化exe文件的当前运行的过程中创建一个COM对象的实例。

但是我发现了一个大问题,我无法解释。以这种方式工作时,我只能通过变型调度方法访问对象。

基本上,如果我的Active X exe文件没有注册,我得到一个“接口不支持”的错误,如果我通过例如接口尝试实例的对象:

WebUpdate:IAutomation;

WebUpdate:= CoAutomation.Create; < - 不工作错误


WebUpdate:Variant;

WebUpdate:= CreateOleObject('WebUpdate.Automation'); < - Works Fine

如果我使用regserver注册active x exe,问题就消失了!

去图!

+0

我不是Delpi的专家,但是从我的理解来看,Delphi com框架与实际在注册表中注册并呈现在类型库(特别是代码正在运行的库)中的内容高度耦合,因此它在呈现SxS时非常有效无效的。但这只适用于接口而不是对象。 我们能够通过组合ROT和接口和类型库(不是CoClasses)的相对注册来绕过这个限制。 – 2010-03-24 22:20:17

+0

相对而言,我的意思是说,在注册表中我们没有把整个路径放到库中,而只是放在\ libName.dll中,这样每个进程都可以在它自己的文件夹中找到libName.dll。 libName.dll甚至可以是流程本身,所以你可以在代码中引用你自己的接口,而不用担心。 – 2010-03-24 22:21:29