【问题标题】:Windows Forms application like Google Chrome with multiple processesWindows Forms 应用程序,例如具有多个进程的 Google Chrome
【发布时间】:2008-10-13 10:15:58
【问题描述】:

有没有什么方法可以使用 C# 来构建一个容器应用程序,其中每个选项卡实际上都是自己的进程,就像 Google chrome 一样?

【问题讨论】:

    标签: c# winforms process


    【解决方案1】:

    您可以使用SetParent Win32 调用来执行此操作,但它确实充满了问题。我在使用来自不同 AppDomain 的窗口时遇到了很多麻烦 - 整个额外进程会更加困难。

    基本上,这两个进程之间可能需要大量通信 - 调整大小之类的事情可能会变得非常痛苦,以及如果子应用想要退出会发生什么等。这一切都是可行的,但我之前会仔细考虑正在做。对于浏览器来说,这很有意义(免责声明:我为 Google 工作)但对于大多数其他应用程序来说,这真的不值得。

    (“标签”是您要创建实际的 .NET 应用程序吗?如果是这样,正如我所说,这将变得容易得多 - 我可以给您一个重要提示,即每个 UI 都应该从内部运行自己的 UI 线程它自己的 AppDomain。如果你不这样做,你会得到非常奇怪的效果!)

    【讨论】:

    • 您的 SetWindow 链接指向一个 SetParent 函数。 (不过,我并没有对此投反对票)
    【解决方案2】:

    对于那些对多进程应用程序的实际实现感兴趣的人,我在我的网站上写了一篇关于它的文章:Multi-process C# app like Google Chrome

    我已经包含了工作 C# 代码。它已经过测试,可与 .NET 2.0、.NET 3.0 和 .NET 3.5 一起使用。

    命名管道:进程如何相互通信

    由于您的问题专门询问了有关 Google Chrome 的问题,您应该知道 Chrome uses named pipes 用于在进程之间进行通信。

    在我上面提到的 C# 源代码中有两个文件:PipeServer.cs 和 PipeClient.cs。这 2 个文件是命名管道 Windows API 的瘦包装器。它经过了很好的测试,因为成千上万的人使用我们的产品。因此,稳定性和稳健性是一项要求。

    我们如何使用多进程设计

    现在您已经掌握了所有的拼图,让我告诉您我们如何在我们的应用中使用多进程设计。

    我们的产品是一个完整的更新程序解决方案。也就是说,有一个程序that builds update patches(与讨论无关)、一个独立的更新程序(wyUpdate - also open source)和一个Automatic Updater control,我们的用户可以在他们的 C# 或 VB.NET 表单中使用。

    我们使用命名管道在独立更新程序 (wyUpdate) 和位于程序窗体上的自动更新程序控件之间进行通信。 wyUpdate 向 Automatic Updater 报告进度,Automatic Updater 可以告诉 wyUpdate 取消进度、开始下载、开始解压等。

    事实上,我们使用的命名管道代码包含在我上面提到的文章中:Multi-process C# app like Google Chrome

    为什么不应该使用多进程设计

    正如上面提到的 Jon Skeet,您应该对多进程模型有特定的需求。在我们的案例中,我们希望将更新程序与您的程序完全分开。这样,如果更新程序以某种方式崩溃,您的程序将毫发无损。我们也不想在 2 个地方重复我们的代码。

    话虽如此,即使使用我们经过充分测试的命名管道包装器,进程间通信也很困难。所以要小心行事。

    【讨论】:

    • 简而言之,Wyatt 的文章很棒。你能分享一下 PipeServer.cs 和 PipeClient.cs 示例消息程序吗? 'Multi-process C# app like Google Chrome' 中的链接似乎已失效。
    【解决方案3】:

    在 Chromium 博客上查看 this post。只有一个进程负责实际呈现到屏幕上。

    【讨论】:

      【解决方案4】:

      我的产品WindowTabs.com 就是这样做的。您需要使用 Win32 - 我建议您避免使用 SetParent,因为您最终会附加线程输入。相反,在窗口上方绘制选项卡并使用 SetWindowPos 将窗口作为一个组移动。此外,如果您在 Win32 级别作为父窗体的父级,某些第三方控件(如 Infragistic)将无法正常工作。

      【讨论】:

      • 这正是我正在寻找的那种行为。您是如何将所有进程绑定到您的应用程序的?当您移动标签栏时,您是如何让他们如此顺畅地移动窗口的?
      【解决方案5】:

      .NET 3.5 中引入的 System.AddIn API 允许您在单独的 AppDomains 中使用 UI 控件。通过一些箍跳,您也可以使其在单独的进程中工作。

      这在 WPF 中得到原生支持。请参阅 MSDN 示例 Add-In Returns a UI

      使用 Windows 窗体,使用 System.AddIn API 似乎无法实现。请参阅来自 System.AddIn 架构师 Jack Gudenkauf 的this post

      但是,WinForms 有一个解决方法。您可以通过一些小技巧来完成这项工作:请参阅 BCL 团队的博客 Support for Windows Forms in System.AddIn Hosts and Add-ins

      【讨论】:

        【解决方案6】:

        是的。您可以使用System.Diagnostics.Process 生成新进程。例如,使用某种形式的inter-process communication (IPC),.NET Remoting,您可以在进程之间进行通信。然后您可以将新进程的窗口/窗体的父级设置为您的第一个进程的窗口(选项卡),以便它出现在那里。

        【讨论】:

          【解决方案7】:

          无需深入研究可扩展性堆栈,您可以使用System.Addin 命名空间来构建一个应用程序,该应用程序本质上可以将插件创建为可视的单独选项卡,并将每个选项卡/插件设置为输出进程,这是一种行为盒子。

          它将具有与 chrome 选项卡相同的功能。

          【讨论】:

            猜你喜欢
            • 2011-08-05
            • 1970-01-01
            • 1970-01-01
            • 2020-06-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多