WPF应用程序,使用HwndHost托管exe,childapp自行关闭,获取无效的窗口处理异常

时间:2015-04-27 21:21:14

标签: c# wpf

如果有一个我用来托管外部可执行文件的WPF应用程序。我使用System.Diagnostics.Process来启动应用程序。

如果hostApp控制了close,可以在process.kill之前调用HwndHost.Dispose(),它运行良好。 DestroyWindowOverride会被调用,并且一切都会消失。

如果childapp关闭,我正在捕获Process.Exited事件。我马上打电话给处理。我没有立即异常或每次异常,但我经常会遇到“无效的Windows句柄”错误的win32Exception。我没有通过DestroyWindowOverride

打电话

我已经尝试清除DataContext,从可视化树中删除对象。试图抓住异常。

我使用的是DwaneNeed.HwndHostEx(HwndHost的派生物)。我希望使用直接的HwndHost会出现同样的问题。

有什么想法吗?

 at MS.Win32.UnsafeNativeMethods.EnableWindow(HandleRef hWnd, Boolean enable)

at System.Windows.Interop.HwndHost.OnEnabledChanged(Object sender,DependencyPropertyChangedEventArgs e)    在System.Windows.UIElement.RaiseDependencyPropertyChanged(EventPrivateKey key,DependencyPropertyChangedEventArgs args)    在System.Windows.UIElement.OnIsEnabledChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)    在System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)    在System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)    在System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)    在System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex,DependencyProperty dp,PropertyMetadata metadata,EffectiveValueEntry oldEntry,EffectiveValueEntry& newEntry,Boolean coerceWithDeferredReference,Boolean coerceWithCurrentValue,OperationType operationType)    在System.Windows.DependencyObject.CoerceValue(DependencyProperty dp)    在System.Windows.UIElement.InvalidateForceInheritPropertyOnChildren(Visual v,DependencyProperty property)    在System.Windows.UIElement.OnIsEnabledChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)    在System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)    在System.Windows.Framew

1 个答案:

答案 0 :(得分:0)

HwndHost有一个IsEnabledChanged事件的处理程序。在实现中,调用了 UnsafeNativeMethods.EnableWindow (_ hwnd,value),这会在子应用程序关闭时抛出异常(不是每次都会抛出,但是经常发生)。

对于此上下文,我能够断开为响应IsEnabledChanged事件而调用的委托。我似乎并不需要它。如果我这样做,我可以将处理程序的实现重定向到我自己的代码,并使用正确的IsAlive检查修复它。

 private void ClearIsEnabledEvent()
    {
        FieldInfo handlerInfo = typeof(HwndHost).GetField("_handlerEnabledChanged", BindingFlags.Instance | BindingFlags.NonPublic);

        // can't do this, HwndHost needs it to be NOT null
        //handlerInfo.SetValue(this,null);

        // replace functionality with my own code (adjust\fix for my own context)
        //handlerInfo.SetValue(this, new DependencyPropertyChangedEventHandler(OnEnabledChanged));

        // in this case, it doesn't appear anything implementation is needed
        // just an empty delegate
        if (handlerInfo != null)
            handlerInfo.SetValue(this, new DependencyPropertyChangedEventHandler(delegate { }));
    }