3

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

我们能够通过编写一个描述我们进程使用的所有库的清单文件,而无需注册,几乎可以为我们所有的 in proc 组件实现这个目标,例如我们的 .net ui、Delphi ui 和我们在 proc 中使用的 COM 服务器在任何组件的客户端上(几乎)。

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

正如我们所知,SxS 不支持进程外 ActiveX 服务器。而且我们不能像在我们的主进程中的 proc com 服务器中那样使用这些对象,因为这将需要对我们的应用程序进行重大重写,甚至更糟糕的是,需要中断第三方工具和供应商使用的面向公众的 API,一个 api我们不能允许的中断。

我们偶然发现了这篇文章,该文章描述了如何从在单独进程中运行的 Internet Explorer 窗口中提取 IHTMLDocument2。这让我们想到了这种方法:

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

此 Delphi ActiveX EXE 和第三方 AciveX EXE 插件之间将采用相同的方法进行通信

有一个替代解决方案,目前我们不喜欢上面提出的解决方案,即使用 .net 远程处理和 .net com 代理类通过将 com 请求转换为 .net 来打开两个进程之间的通信通道远程处理,然后在第二个过程中返回 com。

那么问题来了:

  1. 您如何看待这种方法?
  2. 您看到问题的更好解决方案了吗?
4

2 回答 2

4

这是可能的。需要什么:

  • 应用程序需要自己启动服务器,而不是依赖 COM 来完成。您不需要注册表提供的额外间接,只需使用 CreateProcess()。
  • 服务器应该在其 main() 方法中使用 CoRegisterClassObject() 注册其类工厂。
  • 重要提示:它用于每个工厂的 CLSID 应更改为对每个服务实例都是唯一的。这可确保客户端连接到正确的服务器。我只是将进程 ID 与类工厂 CLSID 进行异或。客户端也知道进程 ID,因此可以进行相同的更改。
  • 应用程序应在循环中调用 CoCreateInstance() 并调用 Sleep() 以等待对象工厂出现。在至少 60 秒过去之前不要宣布失败(这让我很生气)。
  • 应用程序和服务器都需要一个清单,其中包含<file>每个代理/存根 DLL的<comInterfaceExternProxyStub>元素和每个远程接口的元素。
于 2010-01-14T22:52:00.970 回答
0

亚历克斯,

nobugz 是对的,您可以访问运行对象表以从您的 Delphi 自动化 exe 的当前运行进程创建 COM 对象的实例。

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

基本上,如果我的 Active X exe 未注册,如果我尝试通过接口实例化对象,则会收到“不支持接口”错误,例如:

网络更新:自动化;

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


网络更新:变体;

WebUpdate := CreateOleObject('WebUpdate.Automation'); <-- 工作正常

如果我使用 regserver 注册活动的 x exe,问题就会消失!!

去搞清楚!

于 2010-03-23T23:13:31.040 回答