Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#

Tags:

c#

wpf

winapi

You're creating your callback delegate inline in the SetHook method call. That delegate will eventually get garbage collected, since you're not keeping a reference to it anywhere. And once the delegate is garbage collected, you will not get any more callbacks.

To prevent that, you need to keep a reference to the delegate alive as long as the hook is in place (until you call UnhookWindowsHookEx).


IIRC, when using global hooks, if your DLL isn't returning from the callback quick enough, you're removed from the chain of call-backs.

So if you're saying that its working for a bit but if you type too quickly it stops working, I might suggest just storing the keys to some spot in memory and the dumping the keys later. For an example, you might check the source for some keyloggers since they use this same technique.

While this may not solve your problem directly, it should at least rule out one possibility.

Have you thought about using GetAsyncKeyState instead of a global hook to log keystrokes? For your application, it might be sufficient, there's lots of fully implemented examples, and was personally easier to implement.


The winner is: Capture Keyboard Input in WPF, which suggests doing :

TextCompositionManager.AddTextInputHandler(this,
    new TextCompositionEventHandler(OnTextComposition));

...and then simply use the event handler argument’s Text property:

private void OnTextComposition(object sender, TextCompositionEventArgs e)
{
    string key = e.Text;
    ...
}

I have used the Dylan's method to hook global keyword in WPF application and refresh hook after each key press to prevent events stop firing after few clicks . IDK, if it is good or bad practice but gets the job done.

      _listener.UnHookKeyboard();
      _listener.HookKeyboard();

Implementation details here