模拟进程外 ActiveX 的 SideBySide

发布于 2024-08-17 12:55:03 字数 1403 浏览 6 评论 0原文

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

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

差不多的部分来了: 目前,我们的应用程序调用(从它的 C++ 部分)一个进程外 ActiveX 服务器(Delphi ActiveX EXE),该服务器本身又调用另一组进程外 ActiveX 服务器(第三方插件,任何东西都在这里,Delphi, C++,任何东西,只要它不在进程 ActiveX EXE 之外并实现我们的接口)。

据我们所知 SxS 不支持进程外 ActiveX 服务器。我们不能像在主进程中的 proc com 服务器中那样使用这些对象,因为这需要对我们的应用程序进行重大重写,甚至最糟糕的是,破坏我们面向公众的 API(第三方工具和供应商使用的 API)打破我们不能允许的。

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

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

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

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

那么问题来了:

  1. 您对这种方法有何看法?
  2. 您是否看到了更好的问题解决方案?

We are adapting our client side relatively complicated application (ActiveX / .net / Delphi / C++ / COM ) to use SxS to achieve non admin deployment and isolation from older versions of our product.

We were able to achieve this goal for almost all our in proc components such as our .net ui, Delphi ui, and the COM servers we use in proc by composing a manifest file which described all the libraries used by our process, with no registration on the client of any of the components (almost).

And here comes the almost part:
At the moment, our application invokes (from it's c++ portion) an out of proc ActiveX server (Delphi ActiveX EXE), which in turn itself invokes another set of out of proc ActiveX servers (third party plugins, any thing goes here, Delphi, C++, any thing as long as it's out of proc ActiveX EXE and implements our interfaces).

As we know SxS does not support out of proc ActiveX servers. And we can't use these objects as in proc com servers in our main process because that would require a major rewrite of our application and even worst, a break of our public facing API which is used by third party tools and vendors, an api break which we can't allow.

We have stumbled on this article which describes how IHTMLDocument2 can be extracted from an Internet Explorer window running in a separate process. Which made us think of this approach:

We would create a secondary satellite application / process which will run the ActiveX as in process server.
Then we will use LresultFromObject and ObjectFromLresult to transfer a reference of the ActiveX object from the satellite application to the main application process. The satellite application will have it's own manifest file which will allow it to run in SxS mode.

Same approach will be taken to communicate between this Delphi ActiveX EXE and the third party AciveX EXE Plugins

There is an alternative solution, which for the moment we do not prefer over the proposed solution above which is to use .net remoting and .net com proxy classes to open the communication channel between the two processes, by translating the com request to .net remoting, and back to com on the second process.

So here comes the question:

  1. What do you think about this approach ?
  2. Do you see a better solution to the problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

琉璃梦幻 2024-08-24 12:55:04

Alex,

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

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

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

WebUpdate : IAutomation;

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


WebUpdate:变体;

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

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

去图吧!

Alex,

nobugz is right, you can access the Running Object Table to create an instance of a COM Object from a currently running process of your Delphi automation exe.

However I have found a big issue that I cant explain. I can only access the object via the variant dispatch method when working this way.

Basically if my Active X exe is not registered, I get an "Interface Not Supported" error if I try to instance the object through interfaces for example:

WebUpdate : IAutomation;

WebUpdate := CoAutomation.Create; <-- Wont Work Error


WebUpdate : Variant;

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

If I register the active x exe using regserver the problem goes away!!

Go Figure!

心凉 2024-08-24 12:55:03

这是可以做到的。需要什么:

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

It is possible to do. What is needed:

  • An application needs to start a server itself rather than relying on COM to do it. You don't need the extra indirection provided by the registry, just use CreateProcess().
  • A server should register its class factories in its main() method with CoRegisterClassObject().
  • Important: the CLSID it uses for each factory should be altered to be unique for each service instance. This ensures that the client connects to the correct server. I simply XOR the process ID with a class factory CLSID. The client knows the process ID as well so can make the same alteration.
  • The application should call CoCreateInstance() in a loop with a Sleep() call to wait for the object factory to appear. Don't declare failure until at least 60 seconds have passed (that bit me).
  • Both the application and the server need a manifest that contains a <file> element for each proxy/stub DLL and <comInterfaceExternProxyStub> elements for each interface that is remoted.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文