在 WPF 中无缝承载 EXE



我目前的任务是托管一堆旧的 VB6 exes insdide WPF,同时进行看似无限的任务或重构。

托管 EXE 一点也不棘手,但使流程无缝进行。

目前流程为:1) 创建视图2) 注入虚拟机3) 启动进程并触发 EXE。4) 等待输入空闲5) 设置父级6) 设置窗口长7) 设置窗口位置

遇到的问题是,据我所知,使用此方法,进程必须先自然加载,然后才能调用 SetParent。这意味着应用程序在 WPF 控件中休息之前会闪烁。
我想找到一种方法来摆脱这种情况,有没有一种方法可以纯粹在内存中或隐藏中打开进程(我将 UseShellExecute 设置为 true 并且 WindowStyle = ProcessWindowStyle.Minimized)。

可能有一种完全不同的方法可以完全打开我不知道的过程。

视图模型构造函数

 public ShellViewModel()
    {
        WindowWidth = 600;
        WindowHeight = 500;
        MainTitle = "Main Title";
        BreadCrumb = "NA";
        IsLoading = true;
        Task.Factory.StartNew(() =>
        {
            //Process p = OpenProcess(@"C:\Windows\System32\notepad.exe");
            Process p = OpenProcess(@"C:\Program Files\WinRAR\WinRar.exe");
            return p;
        }).ContinueWith(r =>
        {
            try
            {
                Process p = r.Result;
                _handler = p.MainWindowHandle;
                _host.Child = _panel;
                Content = _host;
                int dwStyle = GetWindowLong(_handler, GWL_STYLE);
                SetParent(_handler, _panel.Handle);
                SetWindowLong(_handler, GWL_STYLE, new IntPtr(dwStyle & ~WS_CAPTION & ~WS_THICKFRAME));
                SetWindowPos(_handler, IntPtr.Zero, 0, 0, (int) Math.Round(WindowWidth), (int) Math.Round(WindowHeight) - 106, SWP_FRAMECHANGED);
                BreadCrumb += " Host: " + p.Id.ToString(CultureInfo.InvariantCulture);
                IsLoading = false;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }, UiTaskSchedulerHelper.Instance.UiTaskScheduler);
    }

打开进程

private Process OpenProcess(string path)
    {
        Process p = null;
        lock (locked)
        {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = path;
            psi.UseShellExecute = true;
            psi.WindowStyle = ProcessWindowStyle.Minimized;
            p = Process.Start(psi);
            BreadCrumb += " OpenProcess: " + p.Id;
            p.EnableRaisingEvents = true;
            p.WaitForInputIdle();
        }
        return p;
    }

将示例上传到 github,请随时更新。

https://github.com/OliDow/FormHostPoc/tree/master/FormHostPoc

所以一天的结对编程,我们按预期加载了它。存储库工作正常。 我们还必须将加载 VB6 应用程序设置为在配置文件中最小化启动。

相关内容

  • 没有找到相关文章

最新更新