0
votes

i am working in an application and I press key from keyboard, how can I capture that key (or string), including the source application's name, using C#? i am working on a application, in this application i want to store keystrokes with source application for example if i working with notepad and i type " this is a pen" in notepad.

i have a list view with 3 column( application name, application path, window caption) now in application name column show the program which is open. now if notepad is open then it is showing in list view and i type some text in notepad. i want to store that text in a file which i typed in notepad, this is a console application but i wannna do it in windows 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);

}

3
You want to build a keylogger? What is the purpose? - cjk

3 Answers

1
votes

I don't think that this is best performed with C#, primarily because you will be needing to delve deeply within the Windows API, which obviates the basic presmise behind .NET in that it is platform independent.

As already stated by Anton you'll need to use Windows Hooks and process the WH_KEYBOARD type hook.

0
votes

You probably would like to look at windows hooks.

Implementing what you want isn't a trivial task anyway because in order to get all keystrokes from all windows in the system you must get inside a window message processing mechanism of the operating system.

After all, I wouldn't suggest implementing windows hook that works under CLR. This may be disastrous to the whole OS in case you make a mistake and I'm not sure whether it is even possible.

It means either dig into C/C++ and write a global hook dll intercepting all keystrokes and implement interop with that dll or try to find a way of solving your problem without involving keystrokes capturing.

0
votes

There are many managed wrappers for doing Global System Hooks for mouse and keyboard. The best implementation I've found is :

http://www.codeproject.com/KB/system/globalsystemhook.aspx

This will allow you to set a global keyboard hook and capture keystrokes in notepad. I've used it before and it's very easy to setup. Make sure you unhook when your app terminates.

Now to get the title of the window as you described in the second part of your requirements, you would need to get the current foreground window when you receive the keys from the hook. You can again use the Windows API functions GetForegroundWindow, and GetWindowText for that.
You could also get the process associated with the current foreground window by using Windows API GetWindowThreadProcessID and then using the managed framework System.Diagnostics.Process.GetProcessById() get all sorts of useful information about the source of the keystrokes.

You can look up information on how to implement all said Windows API Functions on pinvoke.net