Low-Level Keyboard Hook in C#
I answered a question today where someone asked for an example of setting a low-level keyboard hook with C#. I actually have an example of doing so in my May 2006 MSDN Magazine article on Managed Debugging Assistants, but the example is purposefully buggy in order to demonstrate the behavior of certain MDAs.
Here is an example without the bug (compile this as a console application):
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
Comments
Anonymous
May 03, 2006
Hi Stephen,
Do you have anything similiar for low-level mouse hook?
Thanks.
Regards,
SoumitraAnonymous
May 03, 2006
Оказывается, это очень просто реализовать. Стивен показывает элементарный примерAnonymous
May 03, 2006
After my last post on implementing low-level keyboard hooks in C#, Soumitra asked if it was possible...Anonymous
May 03, 2006
Soumitra, I didn't, but the code for doing low-level mouse hooks is almost identical to that for low-level keyboard hooks, so I posted a mouse hooks version for you at http://blogs.msdn.com/toub/archive/2006/05/03/589468.aspx. Hope it's helpful.Anonymous
May 03, 2006
Hey
Great piece of code but it doesn't output anything if I press Alt or AltGr. For all other keys it works.Anonymous
May 03, 2006
ALT is a system key and won't be handled by the hook because of the filter for WM_KEYDOWN in HookCallback.Anonymous
May 03, 2006
I added a check for WM_SYSKEYDOWN and got the alt and altgr keys
private const int WM_SYSKEYDOWN = 0x0104;Anonymous
May 10, 2006
great stuff!
I'm wondering how would you check for a combination of CTRL+V or CTRL+ALT+k or similar?
thanx.Anonymous
May 10, 2006
System.Windows.Forms.Control.ModifierKeys should do the trick, telling you whether shift, alt, and/or control are pressed.Anonymous
May 10, 2006
yes that's true :)
but how would i use them in
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
// this doesn't work for me
int vkCode = Marshal.ReadInt32(lParam);
if ((Keys)vkCode == Keys.C && (Keys)vkCode == Keys.Control)
{
Console.WriteLine((Keys)vkCode);
}
}
lParam has only one value, no?
so vkCode is also just one value.
What am i missing here??Anonymous
May 11, 2006
if (Keys.C == (Keys)vkCode && Keys.Control == Control.ModifierKeys)Anonymous
May 11, 2006
thank you very much.Anonymous
July 10, 2006
Thx, very good codeAnonymous
August 09, 2006
Thanks... I have a question. What would be the best way to take input from an attached device like a barcode reader and capture that information, but provide the application different data? Thanks in advanceAnonymous
August 11, 2006
Thinks, very goo-od!Anonymous
September 10, 2006
I have tried the code. But I only get this error
C:Documents and SettingsThomasMy DocumentsVisual Studio ProjectsHooktestInterceptKeys.cs(10): Method 'InterceptKeys.HookCallback(int, System.IntPtr, System.IntPtr)' referenced without parentheses
complaing on this!
private static LowLevelKeyboardProc _proc = HookCallback;Anonymous
September 10, 2006
You're probably using C# 1.x, rather than 2.0. This code is C# 2.0, making use of delegate inference.Anonymous
September 17, 2006
The comment has been removedAnonymous
September 20, 2006
Is there a way to do the same thing in C#.NET 1.1 (as below) or is not possible?
-----
C:Documents and SettingsThomasMy DocumentsVisual Studio ProjectsHooktestInterceptKeys.cs(10): Method 'InterceptKeys.HookCallback(int, System.IntPtr, System.IntPtr)' referenced without parentheses
complaing on this!
private static LowLevelKeyboardProc _proc = HookCallback;Anonymous
September 20, 2006
Rok, if you want to eat the keystrokes, don't call CallNextHookEx when you receive one of them.
Firemaple, sure, just change that to:
private static LowLevelKeyboardProc _proc = new LowLevelKeyboardProc(HookCallback);
C# 2.0 supports delegate inference (where the compiler knows that I wanted to create an instance of LowLevelKeyboardProc and so doesn't make me type it out), a feature new since 1.1.Anonymous
November 10, 2006
Does anyone know how one would go about getting this to work as a Windows Service? When running as a service, the event does not seem to fire. I'm thinking this has something to do with the interactivity of services.Anonymous
November 15, 2006
How can i run KeyboardHook at backgroud and trap all keys at all programs.Anonymous
November 16, 2006
I'm not clear on what you're asking, as the code as it currently exist does intercept the keys for all processes.Anonymous
November 17, 2006
i hav created a hook that will allow u to access all users on any network to do this i just made a hook that allowed u to get all passwords and usernames.Anonymous
December 24, 2006
Hi, This article helped me a lot, presently I am trying to build a MSAA application in c#, there I am using IAccessible object. To get the IAccessble object pointer I need to call the AccessibleObjectFromEvent and need to pass the VARIANT structure. I am stuking here. Can u resolve this problem. Thanks, Raghavendra.Anonymous
January 04, 2007
Cool, works well. If you have the time can you please advise how I can insert keystrokes into the stream. e.g. What I would like to be able to do is hook my "q" key and replace it with two "a" key keystrokes Cheers BeastAnonymous
January 06, 2007
You can send keystrokes to any app using standard window mechanisms and messages, for example the SendInput function from Win32 or the SendKeys.Send method from Windows Forms.Anonymous
January 16, 2007
I can't compile, it gives me an error in the "using System.Windows.Forms;" directive. Is there supposed to be this namespace since this is a console program? Thanks for the codeAnonymous
January 16, 2007
The comment has been removedAnonymous
January 16, 2007
The comment has been removedAnonymous
January 31, 2007
The comment has been removedAnonymous
February 01, 2007
Will it work in Vista. I don't think so because hooking has some issues because of new Securities problems. How should all be done in Vista??Anonymous
February 01, 2007
I don't know what's the reason but I posted this same issue of Vista on many forums but no body use to reply and if some body even reply there is no concrete answer. Everyone revolves around Security Policies or applying XP2 security, but it solves my problem in no way.Anonymous
February 02, 2007
NewUser, yes, it should work in Vista, but not in situations where a lower privileged application tries to control a more privileged application; Vista does include security features to prevent such hijacking. Gary, unfortunately I can't think of any good way to do that without running into a catch-22 situation. Nice idea, though, and best of lucking finding a solution.Anonymous
February 09, 2007
For .Net 1.x, change the Following: private static LowLevelKeyboardProc _proc;// = HookCallback; [...] public static void Main() { _proc += new LowLevelKeyboardProc(HookCallback); _hookID = SetHook(_proc); Application.Run(); UnhookWindowsHookEx(_hookID); }Anonymous
February 28, 2007
hi steohen, i have made this code on windows application not in console after fixing error the program results no yhing could you help me please about how to make it working at windows application thanx.Anonymous
February 28, 2007
hi stephen, i have made this code on windows application not in console after fixing error the program results no thing could you help me please about how to make it working at windows application thanx.Anonymous
March 01, 2007
@Rok: you can 'return new IntPtr(1);' for the key's you want to block.Anonymous
March 02, 2007
Rose, this should work fine in a Windows Forms application as long as you're correctly pumping messages on the thread that installed the hook. Without knowing more about your code, though, I can't help much.Anonymous
March 02, 2007
Thanks for the code Stephen (and suggestions from others)! I needed to trap the function keys to setup a quick navigation within my application. One thing that I noticed is if you did not return quickly the keypress advances to the next hook and this was a problem as I wanted to display a dialog on F1 but the next application was getting the event. So I decided to record the key event, setup a timer for 100ms and process the key event when the timer is raised. This allows for immediate return of (1) which consumes the key press as desired. I hope this helps, and if anyone has a better method please let me know. Cheers Gary.Anonymous
March 14, 2007
Hi Stephen, Actually i am looking to develop a windows service with similar functionality. For ex. if i press key "s" it should save a image. so from the service ""onstart" method i am calling something like this myKeys.RegisterKeyBoardHook();where myKeys is the object of InterceptKeys class and written public void RegisterKeyBoardHook() { <Check to see whether the code pressed is S> { _hookID = SetHook(_proc); StoreImage(); } } in the InterceptKeys class. But when i press the key "s" storeImage is not getting called.. Any help on this.. Regards, RavikanthAnonymous
March 15, 2007
Hi Stephan, Though Its a very worthy article, I am left over with a question. private static IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) { int vkSCode = Marshal.ReadInt32(lParam); if (((Keys)(Keys.S)) == (Keys)vkSCode && ((Keys)(Keys.Control | Keys.Alt) == Control.ModifierKeys)) { StoreImage(); } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } using the above code snippet i am able to trap CTRL+ALT+S How can i implement CTRL+ALT+S+L ??Bcoz there will be only one lParam... Can you please reply me fast.. Regards, RavikanthAnonymous
March 15, 2007
Watch for both WM_KEYDOWN and WM_KEYUP for both keys. You'll need to look for receiving a WM_KEYDOWN for S and one for L before you receive a WM_KEYUP for whatever was received first. You won't just get one event, because there are truly multiple keystrokes here.Anonymous
March 15, 2007
Hi Stephan, I written the code as below.. if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) { if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) { int vkCode = Marshal.ReadInt32(lParam); if (((Keys)(Keys.S)) == (Keys)vkCode) keySPressed = true; if (((Keys)(Keys.L)) == (Keys)vkCode) keyLPressed = true; if (keySPressed && keyLPressed && ((Keys)(Keys.Control | Keys.Alt) == Control.ModifierKeys)) { StoreImage(); } } else if (nCode >= 0 && (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)) { keySPressed = false; keyLPressed = false; } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } But still i am getting lot of calls to "StoreImage". Where i am going wrong ???Anonymous
March 15, 2007
I don't follow the logic you're using. You could try something like the following, though I haven't tested it. In general, I'm happy to try to help when I have time, but I don't have time right now to debug random code. private static bool keySPressed, keyLPressed; private static bool ControlAltPressed { get { Keys mods = Keys.Control | Keys.Alt; return (Control.ModifierKeys & mods) == mods; } } private static IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam) { Keys key = (Keys)Marshal.ReadInt32(lParam); if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { if (key == Keys.S && ControlAltPressed) keySPressed = true; if (key == Keys.L && ControlAltPressed) keyLPressed = true; if (keySPressed && keyLPressed) Console.WriteLine("Pressed"); } else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) { if (key == Keys.S) keySPressed = false; if (key == Keys.L) keyLPressed = false; } return CallNextHookEx(_hookID, nCode, wParam, lParam); }Anonymous
March 15, 2007
Note, too, that the above sample won't catch all corner cases. For example, keySPressed and keyLPressed will remain true even if the user lets go of the Control or Alt keys (while still continuing to hold S and L).Anonymous
April 15, 2007
hi stephen do you have anything similar for the PocketPC regards johnAnonymous
April 20, 2007
Hi Stephan, This is a more general question regarding local hooks. Is it possible to create local hooks for other applications present on the desktop, assuming I know thre thread id of this application? Thanks PhillipAnonymous
April 20, 2007
Hi Stephan, This is a more general question regarding local hooks. Is it possible to create local hooks for other applications present on the desktop, assuming I know the thread id of this application? Thanks PhillipAnonymous
April 20, 2007
Is there a way to just intercept for current process key press? The sample code catch all process key action, right? Thanks, joeAnonymous
April 21, 2007
Joe: Sure, see http://support.microsoft.com/kb/318804. The example traps mouse events, but the code for keyboard events is similar. If you search the Web, you'll find a bunch of additional examples. Philip: You can either create a local hook (just the current process) or a global hook (every process). If you create a global hook, when you receive an event, you can do things like check what window is currently in the foreground to deduce what app will be processing the message, and filter based on that.Anonymous
April 23, 2007
Stephen... So its either local on the current process only OR global on all processes. I have an accounting application that I want to hook and subsequently trap keystrokes to add additional functionalty. I invoked the applications executable using the 'CreateProcess' API, obtained the thread id and defined my hook(s) based on that but the SetWindowsHookEx function failed! Is this approach not possible based on your definition of what you can hook? Thanks Phillip.Anonymous
April 23, 2007
From the documentation: "The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread." Additionally, most global hooks can't be used from .NET... from support.microsoft.com/kb/318804: "Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework. To install a global hook, a hook must have a native DLL export to inject itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export. The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically."Anonymous
April 23, 2007
Thanks. Yes, I was aware of the limitations, costs (performance) and 'danger' of global hooks in .NET, which is why my first choice would have been a local hook. I guess you are saying that I cannot define a hook using the thread id from another process - is that correct? Thanks Phillip.Anonymous
April 23, 2007
The only global hooks that work with .NET (due to the injection issue mentioned previously) are WH_KEYBOARD_LL and WH_MOUSE_LL, and those can't be associated with a particular thread in another app; if you try, you'll get back Win32 error 0x0595: "This hook procedure can only be set globally".Anonymous
April 23, 2007
Okay. I understand the limitations on the scope of global hooks, however that is really not the way I actually want to go anyway. My question was really on local hooks and whether you could use the thread id from another process to define your hook. I guess you are saying you cannot do this and you are suggesting global hooks as an alternative - but bearing in mind their limitations in .NET. Thanks Phillip.Anonymous
May 05, 2007
The comment has been removedAnonymous
May 09, 2007
Hey Stephen, Thanks for the code, but I have one problem though. I have been trying to use the code in a WINFX .NET 3.0 project and I have managed to get it to work by adding System.Windows.Input to the namespace and changing Keys to Key as in: int vkCode = Marshal.ReadInt32(lParam); MessageBox.Show(Convert.ToString((Key)vkCode)); It debugs the project fine but when it comes to pressing a key, rather than showing a D, it outputs a Y instead. Any ideas? ThanksAnonymous
May 09, 2007
The System.Windows.Forms.Keys and System.Windows.Input.Key enumerations have different values (Keys.D == 0x44, Keys.Y == 0x59, Key.D == 0x2F, and Key.Y = 0x44). The former maps more directly to virtual key codes. If you're using WPF, you can use the public static method System.Windows.Input.KeyInterop.KeyFromVirtualKey to convert vkCode into a Key value. -StephenAnonymous
May 09, 2007
Ah right. Thanks for your help! :)
- Dan
Anonymous
May 19, 2007
The comment has been removedAnonymous
June 04, 2007
What do you mean "this isn't working"? How exactly is it not working? Are you getting a compiler error? Is it throwing an exception? etc.Anonymous
June 05, 2007
Firstly... wonderful piece of code. I am building a Keyboard Basher for my baby daughter, and as such want to detect and redirect several keystrokes (like LWin and RWin). Using your sample as part of a Windows form, I have no problem detecting and consuming these keys, but what if I want to act on them (and still not pass them on to the system)? How do I workaround not being able to call a non-static method directly in this code?Anonymous
June 05, 2007
(PS I am using .NET 1.1 and have adapted the code accordingly based on your previous comments)Anonymous
June 10, 2007
I'm using your code to launch an very simple app that allows to copy code snippets from anywhere. It works just fine until I right click on the app tray icon to access its menu. After that, it does fire keyboard events to my app anymore (like it was unhooked). Is it expected? Or am I doing something that's causing this?Anonymous
June 10, 2007
One more thing: I'm using Vista 64-bit.Anonymous
June 15, 2007
Im doing a similar hook in Delphi. I understand that the style is different from c#. I have a basic hook, but it actually traps the keys. I would like them to be read, but still passed on to the application that has focus. How would i do that?Anonymous
June 15, 2007
Varix, just make sure to call CallNextHookEx in all places where you want the keys passed along.Anonymous
July 23, 2007
Will this hook work with 3d games that use Directx?Anonymous
August 03, 2007
Great code. Thank you very much.Anonymous
August 03, 2007
Hi Stephen great code... I have a question. I see that Im not alone, because people asked here before, but no answer... Does anyone know how one would go about getting this to work as a Windows Service? When running as a service, the event does not seem to fire. Can you help Stephen or anyone?Anonymous
August 06, 2007
Hi all Good stuff Stephen and contributers also. I did have the same question as evrastil about running this as a windows service... any ideas or pointers? Thank you,Anonymous
August 06, 2007
For everyone asking about Windows services and hooks, see: http://www.experts-exchange.com/Programming/Languages/CPP/Q_21262041.html?qid=21262041 http://www.codeguru.com/forum/showthread.php?t=389394 http://www.thescripts.com/forum/thread533002.html Hope that helps, StephenAnonymous
August 27, 2007
How in .NET framework 2.0 do I convert the Integer keyCode or IntPtr lParam value to the actual value entered by the user, not one of the Keys enumerators?Anonymous
September 04, 2007
Hi, First of thanks to Stephen Toub for the code. Currently my PC is running an app that changes mode if I press the F12 key. If I run your program it shows all keys except the F12 key (probably that program not passing it up to next hook as eating it up?). How can I make sure that your program first traps the F12 rather than that program? Although my ultimate goal is to not trap the event rather send/generate the F12 keystrokes from my program to change the mode (SendInput using user32.dll does not work, so I think it is using low level hook or something?) of that program using code. ThanksAnonymous
September 05, 2007
Hi, I'm having the same problem Joao had back Jan. 16: I get the error in "using System.Windows.Forms." Apparently he got it to work, but I don't understand the solution. How does one refrence the Windows Forms DLL when compiling? I'm a real noob with C# and I'm using Visual C# 2005 Express. Thanks, EdAnonymous
September 05, 2007
Duh. I found the problem. I needed to add System.Windows.Forms to the references in the Solution Explorer in Visual C# Express. Thanks for the great code, Stephen! EdAnonymous
September 10, 2007
Hi Stephen, Will this code work in the Windows Compact Framework? Im guessing using coredll.dll instead of user32.dll might work for some of those unmanaged commands but im not sure how that would translate with the rest of the code. Thanks, MikeAnonymous
September 19, 2007
Do you know of any more forums related to this topic and a windows service? I've tried the above links and can't find a solution. I wish to temporarily disable the windows and alt+tab system keys which I can't trap in my app. This occurs while a form is visible and then is released when the form is hidden. My service already runs interactively (hence the form appearing), which is a proposed solution on one of the forums. Many thanks for any help on thisAnonymous
September 20, 2007
i'm using ur code for low-level keyboard hook but the above code throw an error "namespace name 'Process' could not be found" even after importing all the namespaced can u plz help me in finding solution thanks Naveen Kushwaha naveenkushwaha@gmail.comAnonymous
October 08, 2007
Hello.. How can I differ between capital letter, other languages letters and regular letters i.e : c and C will give me the same results. also for every other key like b and B. Thanks!Anonymous
October 09, 2007
Bob, you can use GetKeyState from user32.dll to check the status of the shift key, for example.Anonymous
October 10, 2007
But it doesn't gets me if it's other languags. also, if caps lock were hitted it doesn't give me the state. I would like to know which letter has been typed in Hebrew.Anonymous
October 16, 2007
Any solution which make this work on vista.Anonymous
October 19, 2007
The comment has been removedAnonymous
October 23, 2007
Update: I finally resolved this. The code was using the WH_KEYBOARD flag. When run under Vista, the call to SetWindowsHookEx () would fail with a NULL return code. I changed the flag to WH_KEYBOARD_LL and Vista (and other platforms) are once again happy.Anonymous
January 02, 2008
Hey, i want to 'eat up' keys, but your suggestion of not calling CallNextHookEx isn't working. other applications receive input. any other ideas?Anonymous
January 06, 2008
In HookCallback(), instead of returning nothing or the original value how can I return another key value? For example if 'j' was pressed how can I change it so that 'k' was pressed?Anonymous
January 06, 2008
In HookCallback(), instead of returning nothing or the original value how can I return another key value? For example if 'j' was pressed how can I change it so that 'k' was pressed?Anonymous
January 07, 2008
Hi, How can I trap Alt+Tab keys? A similar question has been asked already by Jon on September 20 2007 but I Didn't fined an answer. Thanks, HeziAnonymous
January 10, 2008
I don't know if it is exactly the same ... I want to exchange keypresses like user pressed X but it is replaced with Y. I need it in a way that the following events get the replaced value. this should work like this user presses X >>>
- replace event is called X is replaced with Y
- KeyDown with "Y"
- KeyPress with "Y"
- KeyUp with "Y"
Anonymous
January 11, 2008
Stephen, Thanks for providing your code and keeping up with all the comments/questions that people have added. That's very cool of you. I have another question. I'm using your code - along with the other example you gave for listening to mouse events - to detect whether my windows forms app is currently in use. I'm only interested in events from MY app/process, but when I pass-in the thread id for the current thread, the hook doesn't work. Also, when I just pass in zero as the thread id, my little test app is slow to close (3 or 4 sec compared to almost-instantaneous when the hooks aren't there). I assume this is b/c it's listening for events from all processes. So my question is: how can I set the listener to listen to my app/process only? Or, if that's not possible, how can I speed things up? Thanks in advance. -MattAnonymous
January 12, 2008
Jon, if your goal is to eat the input (not calling CallNextHookEx), make sure you return (IntPtr)1 from the hook callback rather than IntPtr.Zero. Hezi, the code as I have it is looking only for WM_KEYDOWN messages... for alt, you also need WM_SYSKEYDOWN. Hunter and Stephan, see http://support.microsoft.com/kb/33690. Matt, for an example of setting a hook only for the current process, see http://support.microsoft.com/kb/318804.Anonymous
January 15, 2008
Is there anyway, to get the code to write the localized names of the keys out? When I press on "ÆØÅ" (three Danish letters) it says Oemtilde, Oem7 and Oem6. Another thing: Is it possible to get the code not to register the key several times because it is pressed down for a while, so it only tracks the key once everytime you press and 'unpress'?Anonymous
January 18, 2008
I got the keydown fixed! :D Just changed the KEYDOWN to KEYUP and changed the 0x-thingy. I still haven't figured out how to use a specific keyboard layout... :(Anonymous
January 20, 2008
I also can't get this to run as a service, even allowing for interaction with the desktop. All I'm trying to do is get the time of the very last input on an XP machine (with multiple fast user-switching logins). I need to know if any user is still active so my service can react appropriately. Very grateful for any suggestions/comments.Anonymous
February 03, 2008
Hi Stephen, Do you have anything similiar for low-level mouse hook? Thanks.Anonymous
February 04, 2008
http://blogs.msdn.com/toub/archive/2006/05/03/589468.aspxAnonymous
February 19, 2008
Stephen just wanted to thank you for all the hard work you have put in and for the patience while replying back to the questions. Keep up the good work guys!Anonymous
February 22, 2008
Hi - I'm trying to compile your program using Microsoft Visual C# Express Edition, but I get an error in the build process - it says 'The type or namespace name 'Windows' does not exist in the namespace 'System' (are you missing an assembly reference?)' How do I use an assembly reference? Thanks, CaspianAnonymous
February 25, 2008
Hi toub, great code! how to know the difference between eg. a (lowercase) and A (Uppercase)? the same for other( b,B; c,C and so on...) thnk a lot MarkAnonymous
February 25, 2008
You can use GetKeyState from user32.dll to determine the state of the shift key and the caps lock key. Alternatively, you can use Control.ModifierKeys to get the state of the shift key and Console.CapsLock to get the state of the caps lock key; internally, they just use GetKeyState.Anonymous
March 06, 2008
Hi, I want to hook Fn+ keys. For ex Fn+F1..F10. Please advise How to go about it. Thanks a lot.Anonymous
March 27, 2008
i want hook for toggling windowsAnonymous
April 08, 2008
Stephen and Gary, I notice a couple of comments about the issue sendkeys with the control key. I'm getting as Gary mentioned, the control (and alt) keys in addition to my send key string. Can either of you elaborate on the cause and workaround / solution for this situation. Thanks for this great article and thread! RickyAnonymous
April 22, 2008
PingBack from http://rodgerbenham.wordpress.com/2008/04/23/low-level-keyboard-hooks-in-vbnet/Anonymous
May 07, 2008
I am having trouble capturing shift+{any kay} when it is pressed in continuous manner. It goes like this..
- You press shift+a
- Release the 'a' key but dont release the shift key.
- Press 'b'. Here the program is supposed to capture shift+b but it only captures b. I am using GetAsyncKeyState to get the status of shift key. If I release the shift key at step 2 above, the program capture shift+b fine. Am I missing something here?
Anonymous
May 09, 2008
hello i have a problem which seems a bit strange. i have a small program that do the follow: if (vkCode == key) sendkey.sendwait("^c"); when the key is the CTRL key the program runs well. if it's a shift it doesn't. any idea?Anonymous
May 16, 2008
Hi, I want to do something on when key down and also on key up. like onKeyDown() { ///do some thing } onKeyUp() { ///do some thing } I am not familiar with c# and .net please can you help me out.Anonymous
May 16, 2008
The comment has been removedAnonymous
May 16, 2008
I am having trouble capturing shift+{any kay}Anonymous
May 30, 2008
I'm trying do send keys to a directx application (mictosoft train simulator), the classic sendkey doesn't work.... I tryed to see if there's something in the directx to emulate a keypress, but i still haven't found anything. Please help me!!Anonymous
June 04, 2008
Thank you so much this works like a dream. You dont know how much this just helped me!!!Anonymous
June 20, 2008
Is there a way to capture keys from multimedia keyboard? I able to capture all keys except these keys "PLAY","PAUSE", "FORWARD", "REVERSE","HOME", and "POWER". Thank you for your hard work.Anonymous
June 21, 2008
Hello! Thank you for this great piece of code! It helped me a lot. Using the program above, I'm "recording" the keys pressed into a file. Everything is ok, I am able to handle situations when Shift or Caps are pressed. My question: How can I implement a timer so the file gets empty between a specific interval (example: every 10 min. the file is emptied)? I don't know where should I declare the timer. I tried to declare it in Main(), something like: <code> _hookID = SetHook(_proc); System.Timers.Timer timer = new System.Timers.Timer(30000); timer.Elapsed += new ElapsedEventHandler(anotherclass.OnTimedEvent); timer.Enabled = true; Application.Run(); UnhookWindowsHookEx(_hookID); <code> The code above works just ONCE! The file gets emptied once... Thank you. I hope you will reply soon. NicholasAnonymous
June 22, 2008
Hi! Me again... The timer works fine, there was a problem somewhere else in my code... Thanks anyway. NicholasAnonymous
June 25, 2008
kool application... this is what i was looking for from long timeAnonymous
July 01, 2008
Hey, why you use Application.Run() to call the HookCallback() method. Unfortunately, i got an error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." when i suppose to call the "HookCallback()" method without Application.Run(). The error shows in the following code, return CallNextHookEx(_hookID, nCode, wParam, lParam); i'm using another form in my program, hence i need to call "HookCallback()" method without "Application.Run". Is there any way to do like this....Anonymous
July 07, 2008
hi! i am wating for an answer. how can i add a new item to the pop-up menu of the computer(right click). thanks,Anonymous
July 09, 2008
It's very useful code. Thank you a lot.Anonymous
July 22, 2008
Hello All! I am making a service application which logging user activites like mouse moving and key pressing and here comes Hooks. First of all I tried it in a console application and everything was perfect, but when I put the code (and some other) to the service app. and started it, nothing happened. I am sure the code is good. I am running the service in the background with Local System privileges. Is there anybody can help me? Thanks!!Anonymous
July 23, 2008
Okey, I found the way to this. Here is the code: put it in AfterInstall: RegistryKey ckey = Registry.LocalMachine.OpenSubKey(@"SYSTEMCurrentControlSetServicesnServiceName",true); if (ckey != null) { if (ckey.GetValue("Type") != null) { ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 272)); } }Anonymous
August 08, 2008
Hello. I'm working on this bit as a windows service as well, in a Vista 32-bit environment. Unfortunately, this all works well and good until I run it as a service. Then it's all failure. I noticed my service will actually briefly catch keys after the installer runs, but shortly after it's shutdown and when I launch it from my services panel I get nothing. I tried the above mentioned fix, setting my type value to 272, but no avail. Has anyone else found a way around the Windows Service limitations?Anonymous
August 19, 2008
Hi Toub, I have a simple question: Your code captures all key presses globally, right? Is there a way to limit those to a single application, like a way to specify in the hook so that key presses are only captured if that application is in focus? Also do you know how to detect if shift/alt/control keys are pressed? I would like to add these info separately to the eventargs. Should I convert the keycode into Keys? If so, how? Because I am writing a DLL, not exe. Thanks.Anonymous
August 24, 2008
4gGood idea.2f I compleatly disagree with last post . nir <a href="http://skuper.ru">ламинат купить</a> 6rAnonymous
August 28, 2008
Hey i have written code that works perfect on windows and console apps that check all kinds of key combos and it works wonderful. But when i run it inside a service it wont work. This is my opinion services run under a different user session and therefore they catch keystrokes for that user only under which they are running. Now my question is: has anyone had the hook working under a service? If so can you please show us. I have tried a million things and nothing works. Also has anyone been able to run a .NET DLL under svchost? May be thats the answer. I havent been able to do neither one.Anonymous
September 13, 2008
The comment has been removedAnonymous
September 29, 2008
Do you have a code to cature key board ket events using window service without using form. Could you please suggest me where can I find this code Thanks Anil AnilM@ForBiztech.comAnonymous
October 20, 2008
Hi, have you ever tried to use comments in your code? I think they are fundamental.Anonymous
October 24, 2008
原文:http://www.codeproject.com/KB/system/CSLLKeyboard.aspxAnonymous
November 09, 2008
How would I use this in a Windows Form Application?Anonymous
November 13, 2008
Works almost perfect, just for a detail, I opened a instance of notepad and when I tried to close it, takes a lot to close. Any suggestions?Anonymous
November 16, 2008
I have a requirement to alert user that caps key is on. And i dont want to use any heavy interop. Is there any other way to do this. Regards, Pramod Pallath Vasudevan.Anonymous
January 18, 2009
PingBack from http://www.keyongtech.com/1193393-keypress-in-wordAnonymous
January 21, 2009
PingBack from http://www.hilpers.it/2654433-shortcut-key-globaleAnonymous
February 05, 2009
PingBack from http://www.axino.net/tutorial/2009/02/keylogger-in-c-introductionAnonymous
February 06, 2009
Please can someone tell me how to make keyboard hook from windows service? I was trying to allow interact width desktop but it is not working and I don't get any exception...??Anonymous
February 07, 2009
The comment has been removedAnonymous
February 10, 2009
Stephen, I'm writing a service that catch all printscreen and save the image in a directory. My SendHook returns a number, but my HookCallback not respond to any click. Can you help me?Anonymous
February 18, 2009
Thanks much for your code. I'm modified it as an Class. Now I can use it like this: KeyHook newKeyTrap = new KeyHook(); //IMPORTANT - Set Even Handle for KeyHook Return Event newKeyTrap.keyHookReturn += new KeyHook.KeyHookReturn(HookReturn); newKeyTrap.Start(); private void HookReturn(int keyEvent, int vkCode) { //Do Any things with vkCode //You can use System.Windows.Forms.Keys class to check any button is pressed included Multi Media Key //If you don't know the name of that button in Keys Class just write out the vkCode and Find for that code in Keys Class } My Code also can detect which Window is focus in (By the Window Title) Email me if You interested in My Code. ladaidong@yahoo.comAnonymous
February 19, 2009
Thank you very much for your code. 3 years later still helping peoples.Anonymous
February 21, 2009
thanx for the interesting postsAnonymous
February 23, 2009
awesome piece of code. Cheers!Anonymous
March 03, 2009
i have a requirement where i need to create a virtual keyboard and its keys should change on the culture of c# code. Ao if A S D F keys are in english keyboard then if i change the culture to french it should show me French keyboard keys in place of A S D F it should start showing Q S D F does anyone knows how to do that.Anonymous
April 02, 2009
Возникла сегодня задача... Сделать возможность приложению реагировать на нажатие клавиш. Ничего сложногоAnonymous
April 06, 2009
hello....when i compile this code, i'm getting..." Error 1 'WindowsFormsApplication1.Form1.Dispose(bool)': no suitable method found to override " ....i just copy pasted the above code to a new forms application...what do i have to do to make this code work?Anonymous
May 06, 2009
Great Post Dear I was looking exactly the same thing you did. Thanks. Keep it up.Anonymous
June 09, 2009
hi Stephan can you help me. actually i am working on a window application using c#, i wanna know how to capture keystrokes when my window application is active, i wanna know that how to capture keystrokes with source application, please help me out . thanksAnonymous
June 12, 2009
hi Stephan can you help me. actually i am working on a window application using c#, i wanna know how to capture keystrokes when my window application is active, i wanna know that how to capture keystrokes with source application, please help me out . thanksAnonymous
June 24, 2009
Hi Stephan, Great post. I have question about Windows Mobile development. Can we use the same code into the Windows Mobile application? If yes, then what about the OEM keys? Thanks. Regards, Amit RoteAnonymous
June 25, 2009
How to create a keyboard and mouse hook in Visual C++ 2005 Step 1: Create a CWinThread derived thread to house the hook procedures. The documentation tells us that hook procedures can have global or thread state. We are interested in thread state so we place our hook in a thread and then hook the Thread ID of the main .EXE, which can be DOC/VIEW or Dialog based. Step 2: Instantiate the thread that contains the hook in the application. Step 1 Code #define WM_ENDTHREAD WM_APP + 100 // CHookThread class CHookThread : public CWinThread { DECLARE_DYNCREATE(CHookThread) public: CHookThread(int iThreadId = GetCurrentThreadId()); virtual ~CHookThread(); virtual BOOL InitInstance(); virtual int ExitInstance(); public: afx_msg void OnEndThread(WPARAM wParam,LPARAM lParam); protected: int m_iThreadId; static HHOOK m_hKeyBdHook; static HHOOK m_hMouseHook; static LRESULT CALLBACK KeyBdHookProc(int nCode,WPARAM wParam,LPARAM lParam); static LRESULT CALLBACK MouseHookProc(int nCode,WPARAM wParam,LPARAM lParam); protected: DECLARE_MESSAGE_MAP() }; HHOOK CHookThread::m_hKeyBdHook = NULL; HHOOK CHookThread::m_hMouseHook = NULL; IMPLEMENT_DYNCREATE(CHookThread, CWinThread) CHookThread::CHookThread(int iThreadId) : m_iThreadId(iThreadId) { } CHookThread::~CHookThread() { // Unhook the keyboard if (m_hKeyBdHook) { UnhookWindowsHookEx(m_hKeyBdHook); m_hKeyBdHook = NULL; } // Unhook the mouse if (m_hMouseHook) { UnhookWindowsHookEx(m_hMouseHook); m_hMouseHook = NULL; } } BOOL CHookThread::InitInstance() { // Start recording the keyboard messages HINSTANCE hInstance = AfxGetInstanceHandle(); m_hKeyBdHook = SetWindowsHookEx(WH_KEYBOARD,CHookThread::KeyBdHookProc,hInstance,m_iThreadId); if (!m_hKeyBdHook) DebugLastError(); // Start recording the mouse messages m_hMouseHook = SetWindowsHookEx(WH_MOUSE,CHookThread::MouseHookProc,hInstance,m_iThreadId); if (!m_hMouseHook) DebugLastError(); return TRUE; } int CHookThread::ExitInstance() { return CWinThread::ExitInstance(); } // CHookThread message handlers BEGIN_MESSAGE_MAP(CHookThread, CWinThread) ON_THREAD_MESSAGE(WM_ENDTHREAD,&CHookThread::OnEndThread) END_MESSAGE_MAP() // Record the keyboard messages LRESULT CALLBACK CHookThread::KeyBdHookProc(int nCode,WPARAM wParam,LPARAM lParam) { LRESULT Res = CallNextHookEx(m_hKeyBdHook,nCode,wParam,lParam); return Res; } // Record the mouse messages LRESULT CALLBACK CHookThread::MouseHookProc(int nCode,WPARAM wParam,LPARAM lParam) { LRESULT Res = CallNextHookEx(m_hMouseHook,nCode,wParam,lParam); return Res; } void CHookThread::OnEndThread(WPARAM wParam,LPARAM lParam) { // End the thread PostQuitMessage(0); } Step 2 Code In the constructor of the dialog or the view class, create the thread that creates the hook. Make sure to give it the thread id of the current application! // CRemoteDesktopView construction/destruction Ctor::Ctor() { // Hook the keyboard and mouse m_pHookThread = new CHookThread(GetCurrentThreadId()); m_pHookThread->CreateThread(); } Ctor::~Ctor() { // Unhook the keyboard and mouse m_pHookThread->PostThreadMessage(WM_ENDTHREAD,0,0); } This is all there is to it. Of course you are responsible for filling in the code after the actual event is received! In my case, I write PC remote control software and I use journaling to help me control the server by recording the messages on one machine and playing them back on another.Anonymous
July 05, 2009
[url=http://www.mygreek.fm/][img]http://img7.imageshost.ru/imgs/090701/7125a107e6/5380c.png[/img][/url] [b][url=http://www.mygreek.fm/]music from greek [/url][/b]Anonymous
July 12, 2009
I have converted it into vb.net xpress for who ever wants it. Enjoy. Imports System Imports System.Diagnostics Imports System.Windows.Forms Imports System.Runtime.InteropServices Public Class Form1 Private Const WH_KEYBOARD_LL As Integer = 13 Private Const WM_KEYDOWN As Integer = &H100 Private Shared _proc As New LowLevelKeyboardProc(AddressOf HookCallback) Private Shared _hookID As IntPtr = IntPtr.Zero Private Shared Function SetHook(ByVal proc As LowLevelKeyboardProc) As IntPtr Using curProcess As Process = Process.GetCurrentProcess() Using curModule As ProcessModule = curProcess.MainModule Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0) End Using End Using End Function Private Delegate Function LowLevelKeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr Private Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr If nCode >= 0 AndAlso wParam = CType(WM_KEYDOWN, IntPtr) Then Dim vkCode As Integer = Marshal.ReadInt32(lParam) 'Console.WriteLine(CType(vkCode, Keys)) MsgBox(CType(vkCode, Keys).ToString) End If Return CallNextHookEx(_hookID, nCode, wParam, lParam) End Function <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProc, ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr End Function <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr End Function <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr End Function Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load _hookID = SetHook(_proc) Application.Run() UnhookWindowsHookEx(_hookID) End Sub End ClassAnonymous
July 14, 2009
Thanks for the code I found it very very useful but how can we use for disable Alt+F4 ? I tried my best with this code it doesn't work. Actually when pressing Alt+F4 it is not even calling HookCallback function. So, there is no way to track it. Is there anyone know any idea to get around this ?Anonymous
July 21, 2009
Диски blu-ray фильмы по 20$ dvd фильмы диски новинки по 1.8$ в наличии и под заказ, доставка в течении 3х дней [url=http://www.dvd-market.com.ua] [img]http://www.dvd-market.com.ua/products_pictures/SAW4bluray.jpg[/img][/url] наш сайт www.dvd-market.com.uaAnonymous
July 22, 2009
Very interesting site. I appreciate your comment about my black script Do you want a fresh joke from net? Who was Snow White's brother? Egg White. Get the yolk? http://zmyrel.homesta.comAnonymous
July 24, 2009
How to build a [url=http://timezonegames.co.in/_backup/index.php]career in finance[/url]? We know as it to do! In a turning-point the in the most suitable way of all to do a career. We drive avoid you herein :) On our portal you desire catch sight of the first-class suggestions on stint!Anonymous
August 04, 2009
The comment has been removedAnonymous
August 12, 2009
Cool post, I'll try this tonight!Anonymous
August 14, 2009
Hi, I tried your application and it works great except a little problem. May be you can help me out. In the HookCallback function we get the keys like Keys.Oem1, Keys.A etc.. The problem is i want to convert keys.Oem1 to actual characters of the inputed keys that a "real" application sees. I have tried MapVirtualKeyW but it has limitation since it is blind to any keyboard state such as the shift key, etc. i believe WM_CHAR is the correct way to doing it but how :( dont know. i also googled but no luck. Thanks for your help in advanceAnonymous
October 14, 2009
Thanks! I had some code to capture the key press... but without the "Marshal.ReadInt32(lparam)", I didn't know WHICH key was being pressed! This provided the missing link.Anonymous
October 14, 2009
How to eat key strokes? For example, i need to clear key buffer, to avoid print space, when i press WINKEY + SPACE, and perform some operation... private static IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam) { int vkCode = Marshal.ReadInt32(lParam); if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { if ((Keys)vkCode == Keys.LWin || (Keys)vkCode == Keys.RWin) { WinKeyStillPressed = true; } } if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) { if ((Keys)vkCode == Keys.LWin || (Keys)vkCode == Keys.RWin) { //clear flag WinKeyStillPressed = false; } if (WinKeyStillPressed) { if ((Keys)vkCode == Keys.Space) { PlayPauseInner(); // My Styff return CallNextHookEx((IntPtr)0, 0, wParam, (IntPtr)0); // does not eat key strokes return (IntPtr)0; // does not eat key strokes return (IntPtr)1; // does not eat key strokes } if ((Keys)vkCode == Keys.Left) { PlayRewind(); // My Styff } if ((Keys)vkCode == Keys.Right) { PlayForward(); // My Styff } } } return CallNextHookEx((IntPtr)0, 0, wParam, (IntPtr)0); }Anonymous
November 29, 2009
hi all, how to find the name of all the processes receiving key board input.please help me on this... Thanks in advanceAnonymous
December 14, 2009
Hi, Ist id possible to trapp series of keystorkes before pressing enter key?Anonymous
December 14, 2009
I want to trap series of keystrokes i.e "a1de" How is it possible?Anonymous
January 06, 2010
The comment has been removedAnonymous
January 13, 2010
I'm trying to use this code to output a different keyboard char than the one actually typed. The relevant message has been changed to this: private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { //Console.WriteLine((Keys)vkCode); KBDLLHOOKSTRUCT replacementKey = new KBDLLHOOKSTRUCT(); Marshal.PtrToStructure(lParam, replacementKey); replacementKey.vkCode = 90; // char 'Z' Marshal.StructureToPtr(replacementKey, lParam, true); } return CallNextHookEx(_hookID, nCode, wParam, lParam); } Unfortunately this outputs a "A first chance exception of type 'System.ArgumentException' occurred in foobar.exe" every time I press a key. Any idea?Anonymous
January 22, 2010
The comment has been removedAnonymous
March 08, 2010
Nurem >> try this: http://www.pinvoke.net/default.aspx/user32/RegisterHotKey.htmlAnonymous
June 15, 2010
Cool, Do you know how to do the (approx.) equivilant in Visual Basic?Anonymous
June 28, 2010
Thanks for sharing this, I remembered the days of C++ and windows programming.Anonymous
July 06, 2010
I am new to windows programing, and i am trying to trap the ALT+TAB, ALT+ESC.. keys and then disable there action, can you help me to get this done. I need to do it in VB.NetAnonymous
August 29, 2010
I use this sample code in windows 7; and i replace Console.WriteLine((Keys)vkCode) by MessageBox.Show(Convert.ToString((Keys)vkCode)). when it runs, i press one key for 11 times, the hook keyboard is crashed!!!! I don't know why, can you help me plz??????Anonymous
November 06, 2010
This is so helpful! Thanks for sharing.Anonymous
November 28, 2010
Hi, Thanks for the above mentioned code. I was actually searching for something that can hook the keyboard events only for one application i.e. powerpoint 2007. In your code SetWindowsHookEx expects the parameter 0, therefore the hook is applied for all the applications. I do not want that. i only want the hook to be applicable with powerpoint 2007 application. Can you help?Anonymous
December 17, 2010
Thanks for the piece of code it's extremely helpful! :)Anonymous
December 24, 2010
HookCallback() is never called in .NET 4.0 on XP SP3. Am I missing something?Anonymous
January 28, 2011
I know it isn't really a productive comment, but thanks a lot for this!Anonymous
February 03, 2011
Hello, I wanted to see if it is possible to "modify" the hook so that it changes de key pressed, for example: if i press "a", it will display a "b"...Anonymous
February 08, 2011
I would like to know what happens if I don't use the Application.Run(); , it seems that this call is necessary to make it run. But I can't compile using Application.Run() . If I code a windows service how the code should be changed? ThanksAnonymous
February 09, 2011
The comment has been removedAnonymous
February 18, 2011
Does any1 know if I can store this KeyboardHook code in seperate Class or Module ? I dont want to mix all this KeyboardHook with other ode in my form so I would like to have it in external module or class file? I belive this is simple, but I am not so familiar with it ..Anonymous
February 20, 2011
how can i use the same for compact framework??Anonymous
June 09, 2011
hi Stephen, nice article!!! how can i perform this.. ex: first press A and then B after that AB becomes C..? (deleting both A and B) press A -> A press B -> C (generally this is AB) cheersAnonymous
June 15, 2011
my problem is that whe using low level key board hook in a console app, it can get the key information when the app lost focus which is expected, but when I change this code a little bit and make it works in a win form app, it can only get the key information just when the window get focus, but when it lost focus, it cannot get the key information anymore.Anonymous
November 16, 2011
I am trying to run this application as task (on Task Scheduler) on Windows 7 but there is an issue which I couldn't figure out. It might be because of either threading or security? Has anyone run this code as a task or it is not possible?Anonymous
December 05, 2011
Snow still underground rustling, more bitter cold air. When we looked around, neusoft wan to already became a XueSu ice sculpture of the world. Nomura HuangZhong, cold Lin haystack was draped thick.<a href="www.downjacketclearance.com/moncler-c-2.html">women down jacket</a>Anonymous
January 26, 2012
Thanks for this code.Anonymous
February 08, 2012
Thanks, made my tool complete. :)Anonymous
February 08, 2012
Hi Is there a way to know which device send the input? i need to identify the input source because i want to filter the barcode scannerAnonymous
February 16, 2012
Hi, Does this work for WinForm? I've tried it in winform and it's not working. If I comment out the Application.Start(); The winform will no capture the keys. If I leave Application.Start(); then the form will not show but the key capture fires. Is console app codes different than winform code? What am I missing? Thanks, EDAnonymous
February 19, 2012
Error 1 The name 'SetHook' does not exist in the current context c:users****documentsvisual studio 2010ProjectstrycatchtrycatchProgram.cs 29 23 trycatch wat to do?Anonymous
March 10, 2012
Hi there, I'm developing an application which is doing some things in a loop, and this loop have to breaked when any key is entered. I tried the above code but the HookCallback method is called only after the loop. Is there a way i can do any modify in this code to make it work for me ? I looked into it : www.codeproject.com/.../Processing-Global-Mouse-and-Keyboard-Hooks-in-C but it uses a lot of its own classes which is not good. VisualStudio 2010, C#, windows7, .NET 3.5Anonymous
March 21, 2012
The comment has been removedAnonymous
April 22, 2012
The comment has been removedAnonymous
May 18, 2012
That was great thanksAnonymous
August 10, 2012
Im not sure if this will get answered? but im going to ask in any case. Is there a way that we can measure the speed of the current users usage in terms of keyboard mouse activity? not using a prescribed piece of text, like most typing-tutors do, but more along the lines of how fast is the user using the keyboard and mouse independently and in combination? regardless of what the user is actually doing.Anonymous
December 10, 2012
I have used this code in windows service, But it is not detecting any key events. Do you have any idea to handle this in windows service.Anonymous
December 31, 2012
Hi. I'm making stopwatch using the shortcuts and it works when I press 2 times "Home" after opening the program. When I press one time or wait a little after running the program, it will start the stopwatch and nothing else. My code is as follows: private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { vkCode = Marshal.ReadInt32(lParam); if ((Keys)vkCode == Keys.Home) { stopwatch.Reset(); stopwatch.Start(); broken = 0; start = DateTime.Now; while(broken == 0) { elapsed = stopwatch.Elapsed; minutes = (int)elapsed.TotalMinutes; fsec = 60 * (elapsed.TotalMinutes - minutes); //double sec = (int)fsec; tsOut = String.Format("{0}:{1:D2}", minutes, sec); Console.Write("r{0}", tsOut); start = DateTime.Now; while (start.AddSeconds(1) >= DateTime.Now) //it runs for a second { CallNextHookEx(_hookID, nCode, wParam, lParam); vkCode = Marshal.ReadInt32(lParam); if ((Keys)vkCode == Keys.End) broken = 1; } } stopwatch.Reset(); CallNextHookEx(_hookID, nCode, wParam, lParam); } if ((Keys)vkCode == Keys.End) { stopwatch.Reset(); } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } Would you help me with this?Anonymous
January 18, 2013
can you gave the sample program sir of Low-Level Keyboard hook it gonna help me a lot in my study just send me please.. g.jhonmichael@gmail.com thanks you sir....:DAnonymous
March 09, 2013
Hi, with this code how can I hook an USB barcode reader knowing its HID?. Regard. LennyAnonymous
March 20, 2013
having same prob as you reg. ll keyb proc on excel2013, saw your posting on the guy with word2013 prob's, you asked for some help, did you get any answer? my mail is permortenjensen@hotmail.comAnonymous
July 18, 2013
I need one help. i am running application in minized mode and override wndproce() method to capture all windows message.now problem start i do not get windows message when i double click on same application. can u help to figure out it.Anonymous
October 07, 2013
The comment has been removedAnonymous
May 20, 2014
Why I fail to read the barcodes that created by this barcode solution(www.barcodelib.com/csharp)? Is this the barcode quiet zone setting issue?Anonymous
June 02, 2014
barcode scanner sdk for c#.net www.keepdynamic.com/.../csharp-barcode-reader.shtmlAnonymous
September 16, 2014
i have a tool where in i will have to lock the computer if the computer is left idle for 10min while the tool is still running. Please help asap... Thanks in advance!Anonymous
September 25, 2014
Can anyone help ? how to host wcf service in windows service which does keystroke logged and saves it to a file.Anonymous
November 03, 2014
Thank u very much Steph, u're an angel and u'll change the world!!!Anonymous
March 11, 2015
ttomsen, thank u so much ^_^ you helped me to run it in windows form application :) it works ;)Anonymous
March 19, 2015
thanks for sharing this valuable code...Anonymous
September 25, 2015
Canany one help me with hooking DOUBLE tapAnonymous
December 17, 2015
Hello! How I can it ? switch ((Keys)vkCode) { case (Keys.C == (Keys)vkCode && Keys.Control == Control.ModifierKeys): Console.WriteLine("CTRL+C: {0}",(Keys)vkCode); break; case (Keys.V == (Keys)vkCode && Keys.Control == Control.ModifierKeys): Console.WriteLine("CTRL+V: {0}",(Keys)vkCode); break; etcAnonymous
February 23, 2016
I am using the mute key to switch the keyboard to a different language. Is it possible to make the mute key do only this thing without disabling the sound? Thanks.