Размещение EXE-файла в WPF без проблем

В настоящее время мне поставили задачу разместить кучу старых исполняемых файлов VB6 внутри WPF, пока выполняется, казалось бы, бесконечная задача или рефакторинг.

Хостинг EXE не был слишком сложным, но сделать процесс беспрепятственным не составило труда.

В настоящее время поток: 1) Создать представление 2) Внедрить виртуальную машину 3) Запустить процесс и запустить EXE. 4) WaitForInputIdle 5) SetParent 6) SetWindowLong 7) SetWindowPos

Проблема, которую я получаю, заключается в том, что с помощью этого метода, насколько мне известно, процесс должен загружаться естественным образом, прежде чем он сможет вызывать SetParent. Это означает, что приложение мерцает перед тем, как оно остановится в элементе управления WPF.
Я хотел бы найти способ избавиться от этого, есть ли способ открыть процесс чисто в памяти или скрыто ( У меня UseShellExecute установлено значение true, а WindowStyle = ProcessWindowStyle.Minimized).

Возможно, есть другой способ полностью открыть процесс, о котором я не знаю.

Конструктор ViewModel

 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


person Oli    schedule 02.01.2015    source источник
comment
Возможно, psi.WindowStyle=ProcessWindowStyle.Hidden, а позже восстановить стиль окна, как только SetParent будет выполнено.   -  person Erti-Chris Eelmaa    schedule 02.01.2015
comment
@ChrisEelmaa Я пытался заменить Minimized на hidden, и, похоже, это мало повлияло на мерцание. Знаете ли вы какие-нибудь примеры, объясняющие это?   -  person Oli    schedule 02.01.2015
comment
мерцание происходит с любым процессом? Вы также можете комбинировать это: (ProcessWindowStyle.Minimized|ProcessWindowStyle.Hidden)   -  person Erti-Chris Eelmaa    schedule 02.01.2015


Ответы (1)


Итак, день парного программирования, и мы загрузили его, как и предполагалось. Репо работает корректно. Нам также пришлось настроить загрузку приложений VB6 так, чтобы они запускались в свернутом виде в файле конфигурации.

person Oli    schedule 19.01.2015