5

Essentially I want to record every key press (including keydown/keyup and mouse clicks) and when they occurred so that I can create a macro out of them.

I found a ton of stuff about key presses and WinForms or WPF, but I don't really need a GUI, I just want to dump it out to the console after I'm done processing it.

So how can I record all key presses, even when my console window doesn't have focus?


Sample output:

Send {q down}
Sleep 98
Send {q up}
Sleep 4
Send {f down}
Sleep 102
Send {f up}
Sleep 43
Send {a down}
Sleep 26
Send {s down}
Sleep 111
Send {a up}
Sleep 18
Send {s up}
Sleep 17
Send {a down}
Sleep 62
Send {space down}
Sleep 72
Send {a up}
Sleep 5
Send {space up}

Using WPF for now, but the input text field has to be focused. I'd rather be able to record the keystrokes while I'm in my game, hence the question :)

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • 1
    this might help:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx#Y435 – Saher Ahwal Jul 21 '11 at 02:17
  • @Jesus: I suppose it qualifies as a keylogger, yes. – mpen Jul 21 '11 at 02:18
  • @Saher: No..that's winforms again. All my google search results turn up like that, but I don't even have any "controls" to listen on. I just want to get ALL key events, globally, regardless of who or what has focus. – mpen Jul 21 '11 at 02:20
  • Here's a sample C# keylogger that at least should get you down the right path. It's also a winforms app, but utilizes a global hook to log keypresses regardless of what application has focus: http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx – Darth Continent Jul 21 '11 at 02:20
  • 1
    @Jesus: Notice that Mark specified that the key recording would be in a console and used for macros. – Paul Sasik Jul 21 '11 at 02:21
  • @Paul yeah but I mean what else would you call something that reads keys from global keypresses? – Jesus Ramos Jul 21 '11 at 02:48
  • @Jesus: I was reacting to you calling it a keylogger, which is a classic trojan horse app and therefore has negative connotation. So, I thought you were accusing Mark of writing a trojan horse keylogger. – Paul Sasik Jul 21 '11 at 02:59
  • @Paul, yeah it's just that the names match :\ – Jesus Ramos Jul 21 '11 at 03:03

6 Answers6

1

Have a look at the SetWindowsHookEx function. This can be used to monitor keystrokes across the system.

Paul Alexander
  • 31,970
  • 14
  • 96
  • 151
1

As far as I know, in order to accomplish this you will need to hook into Win32 API.

This project may help you get started.

Tom Studee
  • 10,316
  • 4
  • 38
  • 42
1

Just a suggestion, you should take a close look at keyboard low level hooks, they (for the most part) work between consoles and winforms. This might be of some help as well: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

Jess
  • 8,628
  • 6
  • 49
  • 67
1

try this

[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx
    (int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
Yahia
  • 69,653
  • 9
  • 115
  • 144
1

I too was looking for this- found this link which provides a class which does it all :)

http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx

Jack
  • 2,153
  • 5
  • 28
  • 43
1

You can use HwndSource.FromHwnd method to return an HwndSource for

a window where HwndSource represents WPFcontent within a Win32 window

Then AddHook method is used to add a callback method named CallBackMethod,

which will receive all messages for the window. For this, the following code has been used:

HwndSource windowSpecificOSMessageListener = HwndSource.FromHwnd(new 
WindowInteropHelper(this).Handle);
windowSpecificOSMessageListener.AddHook(new HwndSourceHook(CallBackMethod));

In the Callback Method, all the OS messages of this window specific is received.

private IntPtr CallBackMethod(IntPtr hwnd,
int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    // msg can be WM_KEYDOWN = 0x0100, WM_KEYUP = 0x0101 and so forth.
    // Add you code
}
JKhuang
  • 1,523
  • 2
  • 12
  • 14