Windows窗体应用程序,如具有多个进程的Google Chrome
本文关键字:进程 Google Chrome 应用程序 窗体 Windows | 更新日期: 2023-09-27 17:48:54
是否有任何方法可以使用C#来构建一个容器应用程序,其中每个选项卡实际上都是自己的进程,就像Google chrome一样?
您可以使用SetParent Win32调用来执行此操作,但它确实充满了问题。我在使用不同AppDomains的窗口时遇到了很多麻烦——整个额外的过程会有更多的困难。
基本上,这两个过程之间可能需要大量的沟通-调整大小之类的事情可能会变得非常痛苦,以及如果孩子的应用程序想退出会发生什么。这一切都是可行的,但我会在做之前仔细考虑。对于浏览器来说,这很有意义(免责声明:我为谷歌工作),但对于大多数其他应用程序来说,这真的不值得付出代价。
(你想创建真正的.NET应用程序吗?如果是的话,正如我所说,这会变得非常容易,我可以给你一个很大的提示,即每个UI都应该在自己的AppDomain中运行自己的UI线程。如果你不这样做,你会得到非常奇怪的效果!)
对于那些对多进程应用程序的实际实现感兴趣的人,我在我的网站上写了一篇关于它的文章:像谷歌Chrome这样的多进程C#应用程序。
我已经包括了使用C#代码。它已经过测试,可以与.NET 2.0、.NET 3.0和.NET 3.5一起使用。
命名管道:进程如何相互通信
既然你的问题是专门问谷歌Chrome的,你应该知道Chrome使用命名管道在进程之间进行通信。
在我上面提到的C#源代码中有两个文件:PipeServer.cs&这两个文件是命名管道Windows API的精简包装器。它经过了很好的测试,因为成千上万的人使用我们的产品。所以稳定性&健壮性是一项要求。
我们如何使用多流程设计
既然你已经掌握了所有的谜题,让我告诉你我们如何在应用程序中使用多流程设计。
我们的产品是一个完整的更新程序解决方案。也就是说,有一个程序可以构建更新补丁(与讨论无关),一个独立的更新程序(wyUpdate-也是开源的),以及一个我们的用户放在C#或VB.NET表单上的自动更新程序控件。
我们使用命名管道在独立更新程序(wyUpdate)和程序表单上的自动更新程序控件之间进行通信。wyUpdate向自动更新程序报告进度,自动更新程序可以告诉wyUpdate取消进度、开始下载、开始提取等。
事实上,我们使用的确切命名管道代码包含在我上面提到的文章中:多进程C#应用程序,如Google Chrome。
为什么不应该使用多流程设计
正如Jon Skeet上面提到的,您应该对多流程模型有特定的需求。在我们的案例中,我们希望将更新程序与您的程序完全分离。这样,如果更新程序以某种方式崩溃,您的程序将毫发无损。我们也不想在两个地方重复我们的代码。
话虽如此,即使使用我们测试良好的NamedPipes包装器,进程间通信也很困难。所以要小心。
查看Chromium博客上的这篇文章。只有一个进程负责实际渲染到屏幕。
我的产品WindowTabs.com就是这样做的。您需要使用Win32——我建议您避免使用SetParent,因为您最终会附加线程输入。相反,在窗口上方绘制选项卡,然后使用SetWindowPos将窗口作为一个组移动。此外,如果您在Win32级别为窗体设置父级,那么像Infrasistic这样的一些第三方控件将无法正常工作。
.NET 3.5中引入的System.AddIn API允许您在单独的AppDomains中使用UI控件。通过一些环跳,你也可以让它在不同的过程中发挥作用。
这在WPF中得到了导航支持。请参阅MSDN示例"加载项返回UI"。
在使用Windows窗体时,使用System.AddIn API在本机上看起来不太可能。请参阅来自System.AddIn架构师Jack Gudenkauf的这篇文章。
但是,WinForms有一个变通方法。你可以通过一个小技巧来实现这一点:请参阅BCL团队的博客"在System.AddIn主机和外接程序中支持Windows窗体"
是。您可以使用System.Diagnostics.Process生成新进程。使用某种形式的进程间通信(IPC),例如.NET远程处理,您可以在进程之间进行通信。然后,您可以将新流程的窗口/窗体的父级设置为第一个流程的窗口(选项卡),使其显示在那里。
在不深入研究可扩展性堆栈的情况下,您可以使用System.Addin命名空间来构建一个应用程序,该应用程序本质上可以将加载项创建为可视的单独选项卡,并将每个选项卡/加载项设置为输出进程,这是一种开箱即用的行为。
它将具有与chrome选项卡相同的功能。