В настоящее время мне поставили задачу разместить кучу старых исполняемых файлов 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
psi.WindowStyle=ProcessWindowStyle.Hidden
, а позже восстановить стиль окна, как толькоSetParent
будет выполнено. - person Erti-Chris Eelmaa   schedule 02.01.2015(ProcessWindowStyle.Minimized|ProcessWindowStyle.Hidden)
- person Erti-Chris Eelmaa   schedule 02.01.2015