views:

45

answers:

1

I've implemented keyboard hooks in several languages (AutoIt, C#) using SetWindowsHookEx and WH_KEYBOARD_LL. I also know of a couple of C++ programs that have the same issue.

I didn't post any code because they work perfectly in Windows XP. However, under Windows 7, at some point the hooks become "unloaded" or stop processing any further keys. It seems like it may be related to a low memory condition, but I'm not really sure.

Did Microsoft change the way keyboard hooks work in Vista or 7 to add some logic that would unload third-party hooks under certain circumstances?


Related questions:

how to restart a mouse hook?
Detecting Keyboard Hooks

A: 

Well, it's been tinkered with plenty when UAC was implemented in Vista. Nevertheless, this is not a common complaint. Yes, it is quite possible for Windows to stop calling back the hook callback. A built-in feature to prevent the operating system from getting unresponsive when there is one hooker that doesn't handle the callback in a timely manner. It gets automatically removed from the callback list without any diagnostic.

This is based on a timeout and can indeed trip when the OS is starting to run low on resources. Like not having enough RAM and running lots of processes, getting massive paging. More likely with later versions of Windows since they need more RAM and tend to suffer when the machine was upgraded instead of wiped before the install due to disk fragmentation problems (especially the paging file).

The timeout setting can be tweaked by adding the HKCU\Control Panel\Desktop\LowLevelHooksTimeout value (DWORD, say 10000). Ask more questions about it at superuser.com

Hans Passant
That makes a lot of sense. I had read about the LowLevelHooksTimeout but I didn't make the connection between low RAM and the system slowing down. Is there any good way to programmatically detect when my hook becomes unregistered?
jnylen
Yes, you won't get callbacks anymore :)
Hans Passant
No I mean... is there a way my program can detect when Windows has unregistered my hook so that I can reregister it and continue receiving callbacks?
jnylen
http://stackoverflow.com/questions/1465135/detecting-keyboard-hooks mentions a method of enumerating hooks that sounds pretty involved. Other than that, it appears the answer is no.
jnylen
You should do as little work as possible in your hook proc - that way you won't get unregistered. The default timeout is 300ms which should be plenty of time.
Stewart
@Stewart: True, but the point Hans Passant made was that even 300ms can be too short if your application gets paged out to disk. At least, that was the way I interpreted his answer, which seems to make sense.
jnylen