C# 托管窗口时发生BuildWindowCore错误
我正在尝试在进程中主持另一个进程的窗口。 为此,我使用了如下C# 托管窗口时发生BuildWindowCore错误,c#,wpf,C#,Wpf,我正在尝试在进程中主持另一个进程的窗口。 为此,我使用了如下HwndHost: public class MyHandle : HwndHost { #region User32.dll private static Int32 WS_VISIBLE = 0x10000000; private static Int32 WS_CHILD = 0x40000000; private static Int32 WS_BORDER = 0x00800000;
HwndHost
:
public class MyHandle : HwndHost
{
#region User32.dll
private static Int32 WS_VISIBLE = 0x10000000;
private static Int32 WS_CHILD = 0x40000000;
private static Int32 WS_BORDER = 0x00800000;
private static Int32 GWL_STYLE = -16;
[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, IntPtr procid);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);
#endregion
private Action WindowCoreBuilt = null;
private IntPtr m_window = IntPtr.Zero;
public MyHandle(IntPtr window, Action windowCoreBuiltDelegate)
{
m_window = window;
WindowCoreBuilt = windowCoreBuiltDelegate;
}
protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent)
{
int guestStyle = SetWindowLong(m_window, GWL_STYLE, WS_CHILD | WS_BORDER | WS_VISIBLE);
SetParent(m_window, hwndParent.Handle);
HandleRef hwnd = new HandleRef(this, m_window);
InvokeHelper.InvokeDelegate(this.Dispatcher, () => WindowCoreBuilt());
return hwnd;
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
}
}
它通常是有效的,但有时我会遇到这样的例外:
System.InvalidOperationException: BuildWindowCore failed to return the hosted child window handle.
at System.Windows.Interop.HwndHost.BuildWindow(HandleRef hwndParent)
at System.Windows.Interop.HwndHost.BuildOrReparentWindow()
at System.Windows.Interop.HwndHost.OnSourceChanged(Object sender, SourceChangedEventArgs e)
at System.Windows.SourceChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.PresentationSource.UpdateSourceOfElement(DependencyObject doTarget, DependencyObject doAncestor, DependencyObject doOldParent)
at System.Windows.PresentationSource.OnVisualAncestorChanged(DependencyObject uie, AncestorChangedEventArgs e)
at System.Windows.UIElement.OnVisualAncestorChanged(Object sender, AncestorChangedEventArgs e)
stacktrace要深入得多,但我认为这与此无关。我的问题是:
1.是什么原因导致此问题?我如何解决此问题?
2.如何捕获此异常以防止应用程序崩溃?(它发生在我无法访问的系统线程中…) 这是引发异常的特定部分
IsWindow
是函数的直接调用
private void ClearChildControl()
{
if (null == PlayerPanel)
return;
/* this border panel hosts the control of another process */
PlayerPanel.Child = null;
}
我的猜测是,您正在以某种方式从
BuildWindowCore
返回IntPtr.Zero
句柄。一旦子控件进程崩溃,您需要将主机控件内容清除为null。如果您不这样做,并且您导航离开主机窗口,然后返回主机窗口,或者导致应用程序以任何方式重新绘制,则此BuildWindowCore()方法将启动并失败
您可以尝试以下技巧,但需要弄清楚控件的宿主进程。拥有Process对象后,可以执行以下操作:
/* on a seperate thread, monitor the process */
Task.Factory.StartNew(() =>
{
ServiceHostProcess.WaitForExit();
/* back to the UI thread */
Application.Current.Dispatcher.Invoke(ClearChildControl);
});
在我的例子中,ClearChildControl
函数只是将内容清除为null,因此重新绘制尝试甚至不会执行BuildWindowCore
函数
private void ClearChildControl()
{
if (null == PlayerPanel)
return;
/* this border panel hosts the control of another process */
PlayerPanel.Child = null;
}
正如“ghord所说,错误来自HwndHost.BuildWindow
,但是您可以通过确保您提供的HWND不是IntPtr.Zero
,并且它通过以下方式表示窗口来避免此问题:
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool IsWindow(IntPtr hWnd);
但是,如果提供HWND的进程在您为
BuildWindowCore
的调用提供服务时崩溃,那么除了抛出异常或让基类为您执行异常之外,您别无选择。为避免应用程序崩溃,请处理应用程序。DispatcherUnandledException
并将处理的设置为e> 正确
因为这是主要问题。我没有将所有托管儿童清除为空。你救了我一天,马丁!