Forum Discussion
WPF application becomes unresponsive after plugging/ unplugging USB device supporting pen events
I've run across an issue on Windows 10 and 11 where WPF apps seem to become unresponsive when unplugging or plugging in a USB device that registers as an input device that can receive touch/stylus events. This can be seen by creating a basic WPF app in Visual Studio, running it, and then adding/removing one of these devices.
I used Spy++ to see which messages the app was receiving. I saw a number of messages I was expecting to see - WM_DEVICECHANGE, WM_POINTERDEVICECHANGE, as well as 0x02C8 or 0x02C9 (WM_TABLET_ADDED or WM_TABLET_DELETED, respectively). However, after this, thousands (or sometimes tens of thousands) of messages were sent to a window belonging to the app that is at (0,0) with dimensions 0x0. Its caption is "OLEChannelWnd". The messages are mostly the same:
- They're all posted to the window
- The message ID is 0x0400 (WM_USER + 0)
- The wParam is always the same (0x0000BABE)
- The lParam varies each time I restart the WPF app, but they seem to settle on a small number of values - for example, the last time I tried this, I saw 0x05D08BB0 4-6 times, then 0x0D1B8E98 a dozen or more times, then 0x0D1B7B90 several times, and so on.
During these messages, the app would become unresponsive for as long as these messages were posted. This could take upwards of 5- 10 minutes before recovering, and sometimes would result in a crash from the app running out of memory.
After doing research online, I found some posts that talked about a possible issue in the PenThreadWorker thread - that it could be running into some kind of deadlock when initializing certain objects. I also found several posts that mentioned disabling the stylus & touch events by setting "Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport". I can add this to the app.config for my app as follows:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport=true" />
</runtime>
or, equivalently, I can do the following during application startup:
AppContext.SetSwitch("Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport", true);
This does fix the issue - I don't see these WM_USER messages being sent to the app, and as such the app becomes immediately responsive once the device is plugged/unplugged. However, one of the WPF apps that I'm working with (i.e. not the simple test app) needs to process tablet events, so this setting can't be used there. Furthermore, it can only be set either in app.config or during application startup - any calls to it after that are ignored.
I've tried this with .NET 4.5.1, .NET 4.6 (which is required to use the code-based method) as well as .NET 4.8.1, but in all cases I see this same result.
As mentioned, I know this isn't an issue unique to my app since I'm able to reproduce this issue by creating a basic WPF app and following the same steps. Additionally, I observed the same issue with other test applications I've found online while trying to troubleshoot this issue. Interestingly, I have observed this within Microsoft's own Visual Studios 2017 (which is what I'm using for development) and have found a few other threads online from other people running into the same problem with their apps. I have also tried updating to later Visual Studios versions for development of my app, but this doesn't solve the issue either.
Finally, I followed this post from Microsoft regarding https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/disable-the-realtimestylus-for-wpf-applications and still was unable to fix the issue.