0
votes

If have a WPF app that I am using to host external executables. I use System.Diagnostics.Process to start the application.

If the hostApp controls the close and can call HwndHost.Dispose() before the process.kill it works well. The DestroyWindowOverride gets called as it should and everything drops out.

If the childapp closes itself, I am catching the Process.Exited event. I immediately call the dispose. I don't get an immediate exception or an everytime exception, but I will often get a win32Exception with a "invalid windows handle" error. I do not get a call through the DestroyWindowOverride

I've tried clearing the DataContext, removing the object from the visual tree. Tried to catch the exception.

I am using the DwaneNeed.HwndHostEx (a derivative of HwndHost). I expect using a straight HwndHost would be the same problem.

Any thoughts?

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

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

1

1 Answers

0
votes

The HwndHost had a handler for the IsEnabledChanged event. In the implementation there was call to UnsafeNativeMethods.EnableWindow(_hwnd, value) which would throw the exception when the child application was closed (not everytime, but all too often).

For this context, I was able to disconnect the delegate that was called in response to the IsEnabledChanged event. It doesn't appear that I need it. If I did, I can redirect the implementation of the handler to my own code and with the proper IsAlive check fix it.

 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 { }));
    }