使用的setparent窃取另一个进程的主窗口,但保持消息循环分开 [英] Using SetParent to steal the main window of another process but keeping the message loops separate

查看:1778
本文介绍了使用的setparent窃取另一个进程的主窗口,但保持消息循环分开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:我的同事和我保持我们继承了上百万行的遗留应用程序。它的前端是写在VB6,和我们正在致力于几乎所有的资源,将其转换为C#中,我们正在寻找快速和放大器;肮脏的解决方案,我们的具体问题。

Background: My coworker and I are maintaining a million-line legacy application we inherited. Its frontend is written in VB6, and as we're devoting almost all of our resources to converting it to C#, we are looking for quick & dirty solutions to our specific problem.

应用程序的行为在一个插件十岁上下的方式。有迹象表明,可以同时在网格式布局被加载到20ish独立的ActiveX控件。问题在于ActiveX控件做所有的处理自己的UI线程,并为它的很多是在网络接入阻断等待,UI变得非常糊状。当我们的托管C#应用程序加载这些控件,它变得因为多少控件嚼起来UI资源无所事事的响应。最糟糕的是,这些控件是脆弱的,将在挑衅崩溃。当他们在主要的C#应用​​程序托管,这造成了严重的不稳定。

The application behaves in a plugin-ish manner. There are up to 20ish separate ActiveX controls that can be loaded at once in a grid-style layout. The problem is that the ActiveX controls do all of their processing on their own UI thread, and as a lot of it is blocking waiting on network access, the UI gets very soupy. When our hosting C# app loads these controls, it becomes unresponsive because of how many controls are chewing up UI resources doing nothing. To top it off, the controls are fragile and will crash at the slightest provocation. When they are hosted in the main C# app, it creates serious instability.

最好的我的同事和我都拿出了迄今为止已经开始每个ActiveX控件的过程。这个过程,我们称之为代理,是另一个WinForms应用程序。它使用命名管道与宿主进程进行通信。托管进程创建窗口,加载我们选择的一个ActiveX控件(通过一些想法和放大器; AxHost魔法),并告诉主流程是什么它的窗口句柄是通过命名管道。主过程使用的setparent的组合,和SetWindowPos给代理应用移动到本身来模拟一个插件。大小更新是通过命名管道发送。

The best my coworker and I have come up with so far is starting a process per ActiveX control. This process, which we call the proxy, is another winforms app. It uses named pipes to communicate with the hosting process. The hosting process creates a window, loads an ActiveX control of our choice (via some reflections & AxHost magic), and tells the main process what its window handle is via the named pipe. The main process uses a combination of SetParent, and SetWindowPos to move the proxy application into itself to emulate a plugin. Size updates are sent via the named pipe.

这工作得很好,直到该ActiveX应用程序做一些冗长的过程中,我们按一下周围的主窗口上,而它的工作。一段时间的主窗口响应,但最终它作为子窗口等待其UI线程变得无法响应。我们怎样才能保住孩子的窗户上自己的完整的线程同时还获得的setparent好处?

This works well enough until the ActiveX application does some sort of lengthy process and we click around on the main window while it's working. For awhile the main window is responsive, but eventually it becomes unresponsive as the child window waits for its UI thread. How can we keep the child windows on their own complete thread while still getting the benefits of SetParent?

(请让我知道如果有什么不明确!)

(please let me know if anything isn't clear!)

推荐答案

我这样做过。它变得杂乱。

I've done this before. It gets messy.

我们正在运行在其自己的AppDomain中,开始了自己的UI线程每一个插件。我们遇到了很多的真是可恶问题后这样做,当我们的没有的使用不同的UI线程。

We were running every plugin in its own AppDomain, which started up its own UI thread. We did this after running into lots of really nasty issues when we didn't use different UI threads.

这并不意味着你拥有所有跨应用程序域通信的痛苦,但它是可行的。最主要的是,你需要在每个应用程序域/插件运行 Application.Run 。一个巨大的护理量它们之间的沟通 - 甚至关停是棘手的。

It does mean that you have all the pain of communicating across AppDomains, but it's feasible. The main thing is that you'll need to run Application.Run in each AppDomain/plugin. Communicate between them with a huge amount of care - even shutting down is tricky.

祝你好运:)

这篇关于使用的setparent窃取另一个进程的主窗口,但保持消息循环分开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆