Ive seen many solutions online but none does exactly what I want. What is the best/simplest way to get any keys pressed in a given process (not my console applicaton) while my application is running in background. I dont need the modifiers or anything.
-
1This is called [keylogger](http://en.wikipedia.org/wiki/Keylogger) and usually is not a good thing – Steve Dec 21 '12 at 22:46
-
@HenkHolterman youre kidding right ? I want to do something with this key I want to catch it in my app. there MUST be an easy way with the windows handles and stuff.. – phadaphunk Dec 21 '12 at 22:46
-
Ok I know what a keylogger is and thats not what I want. Ill put it in other words. Im playing a game where I have to spam a button so many times it hurts so I want that once I pressed that button, the key automaticly presses itself until I release it. I know how to get it done I juste dont know how to catch if the right key is pressed – phadaphunk Dec 21 '12 at 22:48
-
Have you tried one of those many different ways? Did it satisfy your needs, and if so, why are you unsure to use it? – C.Evenhuis Dec 21 '12 at 22:49
-
Pretty much any solution I found where limited to the application itself :( – phadaphunk Dec 21 '12 at 22:50
-
Then your question is misleading – C.Evenhuis Dec 21 '12 at 22:51
-
Ok im sorry I changed it now do you have anything to say that will help me somehow ? – phadaphunk Dec 21 '12 at 22:51
4 Answers
What you're looking for is called a global keyboard hook. You can find more information and examples on MSDN.

- 26,269
- 6
- 65
- 91
-
Oh I think thats exactly the keyword I was looking for thanks ! I hope its not too hard to implement – phadaphunk Dec 21 '12 at 22:55
If you don't particularly care which process the keys are being pressed in the easiest method would be to call GetAsyncKeyState. It's rather limited though as it does not hook the keyboard and requires you to call it continuously. The best approach in my opinion is to hook the keyboard.
Using SetWindowsHookEx you can actually explicitly specify the identifier of the thread with which the hook procedure is to be associated so you can hook keys for a specific process (see dwThreadId).
Here's a class that you can use (originally found on a Micrsoft blog but I cannot seem to find the authors name at the moment!)
public delegate IntPtr KeyboardProcess(int nCode, IntPtr wParam, IntPtr lParam);
public sealed class KeyboardHook
{
public static event EventHandler<KeyPressedEventArgs> KeyPressed;
private const int WH_KEYBOARD = 13;
private const int WM_KEYDOWN = 0x0100;
private static KeyboardProcess keyboardProc = HookCallback;
private static IntPtr hookID = IntPtr.Zero;
public static void CreateHook()
{
hookID = SetHook(keyboardProc);
}
public static void DisposeHook()
{
UnhookWindowsHookEx(hookID);
}
private static IntPtr SetHook(KeyboardProcess keyboardProc)
{
using (Process currentProcess = Process.GetCurrentProcess())
using (ProcessModule currentProcessModule = currentProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD, keyboardProc, GetModuleHandle(currentProcessModule.ModuleName), 0);
}
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (KeyPressed != null)
KeyPressed(null, new KeyPressedEventArgs((Keys)vkCode));
}
return CallNextHookEx(hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProcess lpfn, IntPtr hMod, uint dwThreadId);
[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);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
}
public class KeyPressedEventArgs : EventArgs
{
public Keys KeyCode { get; set; }
public KeyPressedEventArgs(Keys Key)
{
KeyCode = Key;
}
}
Implementation via Console Application:
class Program
{
static void Main(string[] args)
{
KeyboardHook.CreateHook();
KeyboardHook.KeyPressed += KeyboardHook_KeyPressed;
Application.Run();
KeyboardHook.DisposeHook();
}
static void KeyboardHook_KeyPressed(object sender, KeyPressedEventArgs e)
{
Console.WriteLine(e.KeyCode.ToString());
}
}

- 2,796
- 2
- 25
- 45
-
-
I'm trying to find what to include but I don't have access to KeyPressedEventHandler or any KeyEvents for the matter. How can I access those class ? – phadaphunk Dec 21 '12 at 23:21
-
Ok thanks the fix works. I'm sorry i'm really new to this. Yes I have the class but how can I access the current pressed key from a process with it ? – phadaphunk Dec 21 '12 at 23:43
-
Since reading your comment I've been trying to get it to work but having no luck at all. I thought something like this would suffice: `var threadID = GetWindowThreadProcessId(FindWindowByCaption(0, "Untitled - Notepad"), IntPtr.Zero);` but apparently not. I looked up some articles on SO and found this [post](http://stackoverflow.com/a/4974393/1500199) which is quite deterring. – Caster Troy Dec 22 '12 at 00:25
-
well I know how to find my process but I dont know what to call and what to pass. – phadaphunk Dec 22 '12 at 00:32
-
`return SetWindowsHookEx(WH_KEYBOARD, keyboardProc, GetModuleHandle(currentProcessModule.ModuleName), 0);` The last argument given is the thread id of the process you wish to hook. When you specify 0 the hook procedure is associated with all existing threads. – Caster Troy Dec 22 '12 at 00:37
Oh, so you're looking for "Autofire" in old-school gaming terms?
Instead of writing your own keyboard hook app (unless you're doing it for fun/the thrill of it/the exercise) you might want to look at AutoIt or AutoHotkey, which are both pretty good for keyboard/mouse automation.
See this thread for instance... http://www.autohotkey.com/board/topic/40598-autofire-keyboard/

- 152,115
- 15
- 115
- 172
I have found a way to hook only for a process. You may need it.
int ProcessId = GetProcessesByName("Your_app_here").FirstOrDefault().Id;
private IntPtr SetHook(KeyboardHookHandler proc)
{
return SetWindowsHookEx(13, proc, GetModuleHandle(Process.GetProcessById(ProcessId).MainModule.ModuleName), GetWindowThreadProcessId(GetModuleHandle(Process.GetProcessById(ProcessId).MainModule.ModuleName), out int MainThreadId));
}
Remember to import these methods.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookHandler lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);