Apologies if this has been asked before.
How can I unblock HIDSharp when an application wishes to exit?
I have a solution but I have one doubt about it and would appreciate hearing your thoughts
I have a native windows application (not written by me) that is hosting and running a .net dll plugin (that is written by us).
The native app is taking a very long time to shut down.
The native app is MS Word and we are running a .net VSTO AddIn in it.
Eventually MS Word forcefully shuts itself down and will sometimes disable our AddIn as a result on the next time it starts.
Running HIdSharp's DeviceList.GetHidDevices method starts code that prevents shutdown, but calling that method in a .net console app does not prevent the app shutdown.
Debugging HIDSharp it turns out there is a message loop that is started when calling DeviceList.GetHidDevices.
This message loop calls a native method called GetMessage, that blocks the thread that called it until a message is received.
Because the thread is blocked by unmanaged code, even when calling the managed thread's abort method during shutdown the code does not exit the GetMessage call because at the point it is blocked the thread is in native code and is not managed.
My current solution to the problem is, during out shutdown method's execution, to free the blocked thread my supplying a message to the program. That message is then picked up by the GetMessage.
That in and of itself isn't quite enough though for two reasons:
1.) As GetMessage runs in a loop the message must be of a value that causes the loop to exit (i.e. cause GetMessage to return 0 or 1).
2.) As GetMessage is listening on the main program window's messages the message I send must be to the main program window.
So using the native method PostMessageA in (winuser.h) as follows does the trick:
PostMessageA(hWndOfMainWindow, WM_QUIT, IntPtr.Zero, IntPtr.Zero);
Using WM_QUIT causes GetMessage to return 0. (This is by design in Windows).
hWndOfMainWindow is obtained using the native method CreateWindowEx (HidSharp's WinHIDManager does that itself to obtain the handle too).
One plus side to this solution is that it works without any having to make any changes to HIDSharp's code.
However, it relies on knowing HIDSharp's internals (which could, in theory change in the future).
Also, sending WM_QUIT is potentially problematic because it is a way of telling an application to shut itself down.
In our case, the application is indeed already an a shutdown process so sending WM_QUIT shouldn't be a problem, but I wonder whether the application could interpret the WM_QUIT message as an instruction to cease that very shutdown process that it is in the middle of immediately thus causing the app to shutdown untidily.
I wonder whether you have any thoughts on this.
Have you come across this before?
Is there another way to deal with this problem that can avoid these downsides?
If a solution could be implemented within the code base of HIDSharp, what might that solution be? And in how long do you think you would have something like that on NuGet?