-
-
Notifications
You must be signed in to change notification settings - Fork 112
Keyman Windows FAQs
This page captures informal Slack discussions that contain useful information that is helpful for developers.
keyman64.dll is loaded by dllimport -- The linker stub library keyman64.lib which is linked into keymanx64.exe loads it on process startup.
This is a major problem -- SetWindowsHookEx causes the DLL to be loaded into the process space of each process in the same session which has at least one thread with a message queue. This happens asynchronously whenever the next message is received into each thread's message queue (as part of the GetMessage and PeekMessage APIs). The problem is that UnhookWindowsHookEx uses exactly the same mechanism to unload the DLL -- when the next message is received into the process's message queue. So if a thread isn't receiving messages, which can be for a large number of reasons, including:
- there just are no messages for windows owned by the thread, which is a common situation for invisible worker windows;
- the process/thread is suspended;
- the thread previously created a window but no longer has any windows and so is no longer calling GetMessage/PeekMessage;
- the thread has hung or is busy;
- the thread decided not to call GetMessage/PeekMessage for some reason of its own.
There may also be other reasons why the Windows hook mechanisms don't get the opportunity to load/unload the hook DLL, including security mechanisms. We play some games to try and flush out locks, like posting a junk message to every window on the system, which addresses the first scenario in the above list. But the last three scenarios are impossible to solve from our end. Technically they could be considered bugs I guess? Making things worse is the reality that TSF also loads our DLLs into memory and controls the lifecycle of them. The only guaranteed way to unload them is to uninstall the TIP, which is not an easy round-trip solution, as it causes TIPs to be reordered, and in the case of transient language IDs, can change the transient language codes and require the whole transient language reinstall schmozzle. Note: it seems we still need hooks despite using TSF, due to limitations of the TSF keystroke callbacks, in particular, to do with modifier keys. It would be great to eliminate these hooks. Maybe one day it will be possible to do so.