Я использую код, размещенный в этом вопросе, с некоторыми незначительными изменениями: Внедрение приложения Unity3D в WPF * без * того, чтобы оно занимало все окно
Этот подход работал отлично, нокогда я смотрю на процессы менеджера задач.Имя моего основного исполняемого файла WPF удаляется из процесса, когда я выхожу со страницы, на которой запущен проигрыватель Unity Player, и загружаю другую страницу.Приложение по-прежнему работает просто отлично.Диспетчер задач просто показывает значок без имени процесса рядом с ним.Это только проблема, потому что у меня есть другая фоновая служба, которая контролирует мое приложение WPF и запускает и останавливает его удаленно на основе его имени.Любое предложение?
Код страницы показан ниже.
public System.Windows.Forms.Integration.WindowsFormsHost host = new System.Windows.Forms.Integration.WindowsFormsHost();
[DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private Process process;
private IntPtr unityHWND = IntPtr.Zero;
private const int WM_ACTIVATE = 0x0006;
private readonly IntPtr WA_ACTIVE = new IntPtr(1);
private readonly IntPtr WA_INACTIVE = new IntPtr(0);
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
bool initialized = false;
public UnityPlayer()
{
InitializeComponent();
if (this.grid1.Children.Count == 0)
{
this.grid1.Children.Add(host);
}
dispatcherTimer.Tick += attemptInit;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
void attemptInit(object sender, EventArgs e)
{
if (process != null)
{
if (process.HasExited)
{
Thread.Sleep(1000);
FSC.GoHome();
}
}
if (initialized)
return;
HwndSource source = (HwndSource)HwndSource.FromVisual(host);
Console.WriteLine("attempting to get handle...");
if (source == null)
{
Console.WriteLine("Failed to get handle source");
return;
}
IntPtr hWnd = source.Handle;
try
{
process = new Process();
process.StartInfo.FileName = "Block Breaker.exe";
process.StartInfo.Arguments = "-parentHWND " + hWnd.ToInt32() + " " + Environment.CommandLine;
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForInputIdle();
// Doesn't work for some reason ?!
//unityHWND = process.MainWindowHandle;
EnumChildWindows(host.Handle, WindowEnum, IntPtr.Zero);
//unityHWNDLabel.Text = "Unity HWND: 0x" + unityHWND.ToString("X8");
Console.WriteLine("Unity HWND: 0x" + unityHWND.ToString("X8"));
panel1_Resize(this, EventArgs.Empty);
initialized = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ".\nCheck if Container.exe is placed next to UnityGame.exe.");
}
}
private void ActivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
}
private void DeactivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
}
private int WindowEnum(IntPtr hwnd, IntPtr lparam)
{
unityHWND = hwnd;
ActivateUnityWindow();
return 0;
}
private void panel1_Resize(object sender, EventArgs e)
{
MoveWindow(unityHWND, 0, 0, (int)host.Width, (int)host.Height, true);
Console.WriteLine("RESIZED UNITY WINDOW TO: " + (int)host.Width + "x" + (int)host.Height);
ActivateUnityWindow();
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
dispatcherTimer.Stop();
dispatcherTimer = null;
host.Dispose();
}
Процесс показа изображения до загрузки страниц
Процесс показа изображения во время процессастраница запущена
Процесс показа изображения После выхода из страниц и загрузки новой страницы