在面板中检测新应用并 运行

Detect new app and run it in panel

我正在创建在面板内运行另一个应用程序的应用程序。

[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

public Form3() {
    InitializeComponent();

}

private void button1_Click(object sender, EventArgs e) {
    Process p = Process.Start(@"path\app.exe");
    Thread.Sleep(200); // Allow the process to open it's window
    SetParent(p.MainWindowHandle, panel1.Handle);
}

但问题是,app.exe 有时(我知道什么时候)会创建新的 window 作为新应用程序。我想将这个新 window 添加到新面板中。

private Process GetProcess() {
    //do some magic stuff and find actually running app
    return NewAppProcess;
}

private void button2_Click(object sender, EventArgs e) {
    Process p = GetProcess();
    SetParent(p.MainWindowHandle, panel2.Handle);
}

感谢所有能把我推向正确道路的一切

使用ManagementEventWatcher, you can watch Win32_ProcessStartTrace 在新进程启动时接收事件。

例子

在此示例中,我展示了如何观看 mspaint.exe 的开始并将其添加为表单中 Panel 的子项。为此,将对 System.Management dll 的引用添加到您的项目中,然后使用以下代码。

注意 1: 观察者的速度不是很快,您可能会看到 window 在桌面上打开然后坐在面板中。

注2:这是一个例子,用mspaint.exe做起来很热。如果您在实际 app.exe 上应用该解决方案时遇到任何问题,您需要专门询问 app.exe.

的解决方案

注意 3:确保您 运行 是管理员。

using System.Management;
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    ManagementEventWatcher watcher;
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        watcher = new ManagementEventWatcher(
            "Select * From Win32_ProcessStartTrace Where ProcessName = 'mspaint.exe'");
        watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
        watcher.Start();
    }
    void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
        var id = (UInt32)e.NewEvent["ProcessID"];
        var process = System.Diagnostics.Process.GetProcessById((int)id);
        this.Invoke(new MethodInvoker(() => {
            SetParent(process.MainWindowHandle, panel1.Handle);
        }));
    }
    protected override void OnFormClosed(FormClosedEventArgs e)
    {
        watcher.Stop();
        watcher.Dispose();
        base.OnFormClosed(e);
    }
}