在我们的进程窗口中托管第三方应用程序的代码(例如 Google Chrome、Internet Explorer 8)






4.50/5 (12投票s)
此代码演示了如何在您自己的进程窗口中托管第三方应用程序,例如 Google Chrome 和 Internet Explorer 8。
引言
此代码演示了如何在应用程序的窗口中托管第三方应用程序的用户界面。在下面的示例应用程序中,记事本.EXE 将在我的进程中托管。记事本应用程序在我们的应用程序调整大小时也会自动调整大小。同样,任何图形应用程序都可以托管在单独的进程中。对于延迟加载的图形应用程序,托管进程必须等到被托管进程的 MainWindow
创建完成后才能继续,因此,作为一种替代方案,我使用了 Thread.Sleep
来等待一到两秒钟。示例应用程序可在此处 下载。

优点
- 被托管进程的生命周期可以在托管进程内进行管理。
- 如果被托管进程崩溃,可以进行适当的处理。
- 这种进程的托管和管理对于看门狗之类的应用程序非常有用,在这种情况下,如果被托管进程宕机或崩溃,可以将其重新启动。同样,所有这些都在一个窗口内完成。
- 通过一些窗口坐标计算,被托管的应用程序可以进行平铺/层叠等操作。
示例
著名的Google Chrome、Internet Explorer 8,其中 Internet Explorer/Chrome 窗口的每个标签页都是一个进程。我在分割器窗口中托管了 GUI,而 Internet Explorer 8/Chrome 则将它们托管在选项卡中。
Using the Code
使用两个 Win32 API 在我们的进程中托管第三方应用程序的窗口。
SetParent 和 SetWindowPos
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int X, int Y, int cx, int cy, uint uFlags);
SetParent
API 用于设置第三方应用程序主窗口句柄的父窗口句柄。在这种情况下,我的应用程序的窗口句柄是第三方应用程序(Notepad.exe)主窗口的父窗口。
SetParent(p.MainWindowHandle, this.splitContainer2.Panel1.Handle);
SetWindowPos
API 用于在我们调整应用程序大小时调整第三方应用程序窗口的大小。
SetWindowPos(p.MainWindowHandle, HWND_TOP,
this.splitContainer2.Panel1.ClientRectangle.Left,
this.splitContainer2.Panel1.ClientRectangle.Top,
this.splitContainer2.Panel1.ClientRectangle.Width,
this.splitContainer2.Panel1.ClientRectangle.Height, SWP_NOACTIVATE | SWP_SHOWWINDOW);
关注点
任何图形应用程序都可以托管在单独的进程中。这样做的优点是,如果图形应用程序崩溃,托管它的应用程序仍然保持运行,并且可以采取适当的措施。我无法将某些应用程序(如 Internet Explorer (Iexplore.exe)、Microsoft Word (winword.exe))托管到我自己的应用程序窗口中。要托管这些进程,在调用 WaitForInputIdle
函数后,我必须等待一秒钟(调用 Thread.Sleep(1000))
)。我真的不知道其中的原因。如果您知道原因,请告诉我。
历史
- 2010年8月16日:初始帖子