microsoft / dotnet

This repo is the official home of .NET on GitHub. It's a great starting point to find many .NET OSS projects from Microsoft and the community, including many that are part of the .NET Foundation.
https://devblogs.microsoft.com/dotnet/
MIT License
14.34k stars 2.21k forks source link

.Net 4.7/4.8 WPF: App crashes on touch input event when Win32k checks hardware in the background #1132

Open vcpp opened 4 years ago

vcpp commented 4 years ago

WPF application sporadically crashes with NullReferenceException thrown from System.Windows.Input.StylusWisp.WispStylusDevice.TabletDevice.

There are several stacktrace variations:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Input.StylusWisp.WispStylusDevice.get_TabletDevice()
   at System.Windows.Input.StylusTouchDeviceBase..ctor(StylusDeviceBase stylusDevice)
   at System.Windows.Input.StylusWisp.WispLogic.PromoteMainToMouse(StagingAreaInputItem stagingItem)
   at System.Windows.Input.StylusWisp.WispLogic.PromoteMainDownToTouch(WispStylusDevice stylusDevice, StagingAreaInputItem stagingItem)
   at System.Windows.Input.StylusWisp.WispLogic.PromoteMainToTouch(ProcessInputEventArgs e, StylusEventArgs stylusEventArgs)
   at System.Windows.Input.StylusWisp.WispLogic.PromoteMainToOther(ProcessInputEventArgs e)
   at System.Windows.Input.StylusWisp.WispLogic.PostProcessInput(Object sender, ProcessInputEventArgs e)
   at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.StylusWisp.WispLogic.InputManagerProcessInput(Object oInput)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
   в System.Windows.Input.StylusWisp.WispStylusDevice.get_TabletDevice()
   в Microsoft.Surface.Presentation.Input.TouchExtensions.IsTouchPromotedStylusDevice(StylusDevice stylusDevice)
   в Microsoft.Surface.Presentation.Input.TouchExtensions.HandleMouseLeave(MouseEventArgs e, Action`1 inputLeave)
   в System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   в System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   в System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   в System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   в System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   в System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList`1 otherOrigins, DeferredElementTreeState& oldTreeState, Action`2 originChangedAction)
   в System.Windows.Input.MouseDevice.ChangeMouseOver(IInputElement mouseOver, Int32 timestamp)
   в System.Windows.Input.MouseDevice.PreProcessInput(Object sender, PreProcessInputEventArgs e)
   в System.Windows.Input.InputManager.ProcessStagingArea()
   в System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   в System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   в System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   в System.Windows.Interop.HwndMouseInputProvider.PossiblyDeactivate(IntPtr hwndCapture, Boolean stillActiveIfOverSelf)
   в System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   в System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   в System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Crashes are being accompanied by the following events:

Event ID Source Description En (supposed) Description Ru (actual)
7040 Service Control Manager The start type of the Touch Keyboard and Handwriting Panel Service service was changed from demand start to auto start Тип запуска службы "Служба сенсорной клавиатуры и панели рукописного ввода" был изменен с "Вручную" на "Автоматически"
267 Win32k Touchpad Hardware Quality Assurance verification succeeded Проверка качества оборудования с возможностью сенсорного ввода/сенсорной панелью выполнена
7040 Service Control Manager The start type of the Touch Keyboard and Handwriting Panel Service service was changed from auto start to demand start Тип запуска службы "Служба сенсорной клавиатуры и панели рукописного ввода" был изменен с "Автоматически" на "Вручную"

WispStylusDevice provides IsValid property that should presumably be checked before accessing TabletDevice property, but some usages don't take that IsValid into account expecting TabletDevice to be null for invalid state:

internal StylusTouchDeviceBase(StylusDeviceBase stylusDevice)
    : base(stylusDevice.Id)
{
    this.StylusDevice = stylusDevice;
    this._stylusPointDescription = this.StylusDevice?.TabletDevice?.TabletDeviceImpl?.StylusPointDescription ?? this._stylusPointDescription;
    this.PromotingToOther = true;
}
private static bool IsTouchPromotedStylusDevice(StylusDevice stylusDevice)
{
    if (stylusDevice != null && stylusDevice.TabletDevice != null)
        return stylusDevice.TabletDevice.Type == TabletDeviceType.Touch;
    return false;
}

Questions:

  1. Should I provide some additional information needed to locate and fix the bug?
  2. Could you please suggest a workaround which could be used in production environment?
  3. May I expect this to be fixed in .Net Framework? Migrating to .Net Core will take some time.
vcpp commented 4 years ago

Related SO question: Touch, Framework 4.7, multiple windows & Windows Creator Update

Sebbstar commented 3 years ago

same problem with same stacktrace here. Are there any suggestions for a workaround?

yy-2020 commented 3 years ago

we have the same Problem here with the same stacktrace. Any updates for this issue?