Мне посчастливилось получить кучу старых VB6 exes insdide WPF, в то время как, казалось бы, бесконечная задача или рефакторинг.Хостинг EXE в WPF кажущийся
Хостинг EXE не был слишком сложным, но при этом процесс казался безвкусным.
В настоящее время поток: 1) Создать вид 2) Inject VM 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', а затем восстановить windowStyle, как только будет выполнен« SetParent ». –
@ChrisEelmaa Я попытался обменять Minimized для скрытых, и он, похоже, практически не повлиял на мерцание. Знаете ли вы какие-либо примеры, которые могли бы объяснить это? – Oli
происходит ли мерцание с любым процессом? Вы также можете комбинировать: '(ProcessWindowStyle.Minimized | ProcessWindowStyle.Hidden)' –