如何在 wpf 应用程序中运行应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6477851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:56:25  来源:igfitidea点击:

How to run an application inside wpf application?

wpf

提问by user617275

My question is how to run an application(.exe) inside WPF application. I mean running inside a window of an application, not an external running an application.

我的问题是如何在 WPF 应用程序中运行应用程序(.exe)。我的意思是在应用程序的窗口内运行,而不是在外部运行应用程序。

Thanks in advance :D

提前致谢

回答by Youngy

What you are looking to do is entirely possible, but it does come with a few bugs, so don't expect an easy ride. What you need to do is create a class that inherits from HwndHostand overrides the BuildWindowCore()method. See the example from Microsoft at http://msdn.microsoft.com/en-us/library/ms752055.aspx

您想要做的事情完全有可能,但它确实存在一些错误,因此不要指望轻松完成。您需要做的是创建一个继承HwndHost并覆盖该BuildWindowCore()方法的类。请参阅 Microsoft 的示例,网址http://msdn.microsoft.com/en-us/library/ms752055.aspx

In the above example, they give you the notion of being able to put a Win32 control within your WPF form, but you can use the same architecture to load the MainWindowhandleof your created Notepad process into the child of the border. Like this:

在上面的示例中,它们为您提供了能够在 WPF 表单中放置 Win32 控件的概念,但您可以使用相同的体系结构将MainWindowhandle您创建的记事本进程加载到边框的子进程中。像这样:

protected override HandleRef BuildWindowCore(HandleRef hwndParent)
    {
        ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
        psi.WindowStyle = ProcessWindowStyle.Minimized;
        _process = Process.Start(psi);
        _process.WaitForInputIdle();

        // The main window handle may be unavailable for a while, just wait for it
        while (_process.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Yield();
        }

        IntPtr notepadHandle = _process.MainWindowHandle;

        int style = GetWindowLong(notepadHandle, GWL_STYLE);
        style = style & ~((int)WS_CAPTION) & ~((int)WS_THICKFRAME); // Removes Caption bar and the sizing border
        style |= ((int)WS_CHILD); // Must be a child window to be hosted

        SetWindowLong(notepadHandle, GWL_STYLE, style);
        SetParent(notepadHandle, hwndParent.Handle);

        this.InvalidateVisual();

        HandleRef hwnd = new HandleRef(this, notepadHandle);
        return hwnd;
    }

Please keep in mind that you will need to import a few functions from the User32.dll to be able to set the style of the window and set the parent window handle:

请记住,您需要从 User32.dll 导入一些函数才能设置窗口的样式和设置父窗口句柄:

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

Also make sure that you are including:

还要确保您包括:

using System.Windows.Interop;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

This is my first answer on a forum so please let me know if it needs some work. Also reference Hosting external app in WPF windowbut don't worry about DwayneNeed stuff. Just use SetParent() as you see in my code above. Just be careful if you try embedding the app inside a tab page. You will encounter some fun there.

这是我在论坛上的第一个回答,所以请让我知道它是否需要一些工作。还可以参考WPF 窗口中的 Hosting external app,但不要担心 DwayneNeed 的东西。正如您在上面的代码中看到的那样,只需使用 SetParent() 即可。如果您尝试将应用程序嵌入到标签页中,请务必小心。你会在那里遇到一些乐趣。