14

First of all I need to make it clear that I have no interest in keylogging.

I need a way to monitor keyboard activity at the most basic level while my application is in the background. I don't need to know which keys, I don't need to save any data, I don't need or plan to hide my application at all, all I need is to know when keys are pressed and invoke a method.

I'm looking for the simplest way to do this possible, I know a reasonable amount of C# but nothing too complex as most of my knowledge is self-taught.

I've looked around for some appropriate ways of doing this and I've found nothing useful. All I've found is a bunch of people saying "No, that's illegal" on forums and source code for in depth keyloggers.

If any of you could advise me on a way to achieve this then I would be most appreciative.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Tane Lattanzio
  • 143
  • 1
  • 1
  • 6

4 Answers4

6

You'll need to use Window Hooks:

Low-Level Keyboard Hook in C#

But beware, Windows security, may be protecting us from doing what you want!

Justin
  • 84,773
  • 49
  • 224
  • 367
Mesh
  • 6,262
  • 5
  • 34
  • 53
5

You can monitor keyboard and mouse activity in the background with the Nuget package MouseKeyHook (GitHub).

This code detects when a key is pressed:

    private IKeyboardMouseEvents _globalHook;

    private void Subscribe()
    {
        if (_globalHook == null)
        {
            // Note: for the application hook, use the Hook.AppEvents() instead
            _globalHook = Hook.GlobalEvents();
            _globalHook.KeyPress += GlobalHookKeyPress;
        }
    }

    private static void GlobalHookKeyPress(object sender, KeyPressEventArgs e)
    {
        Console.WriteLine("KeyPress: \t{0}", e.KeyChar);
    }

    private void Unsubscribe()
    {
        if (_globalHook != null)
        {
            _globalHook.KeyPress -= GlobalHookKeyPress;
            _globalHook.Dispose();
        }
    }

You will need to call Subscribe() to start listening, and Unsubscribe() to stop listening. Obviously you need to modify GlobalHookKeyPress() to do useful work.

I needed this functionality in order to write a utility which will turn on the keyboard backlight on a Lenovo Thinkpad when any key is pressed, including CTRL (which KeyPress doesn't catch). For this purpose, I had to monitor for key down instead. The code is the same except we attach to a different event...

    _globalHook.KeyDown += GlobalHookOnKeyDown;

and the event handler signature is different:

    private static void GlobalHookOnKeyDown(object sender, KeyEventArgs e)
    {
        Console.WriteLine("KeyDown: \t{0}", e.KeyCode);
    }

The library can also detect specific key combinations and sequences. For example:

    Hook.GlobalEvents().OnCombination(new Dictionary<Combination, Action>
    {
        { Combination.TriggeredBy(Keys.A).Control(), () => { Console.WriteLine("You Pressed CTRL+A"); } },
        { Combination.FromString("Shift+Alt+Enter"), () => { Console.WriteLine("You Pressed FULL SCREEN"); } }
    });
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
2

Microsoft tells you How to: Handle Keyboard Input at the Form Level. As long as you handle the same event(s) this works for any non web application.

You should also take a look at the other questions here on SO, such as Handling Input from a Keyboard Wedge

Community
  • 1
  • 1
Joshua Drake
  • 2,704
  • 3
  • 35
  • 54
0

You could register Windows Hot Key with RegisterHotKey windows API, look at this blog post :

http://www.liensberger.it/web/blog/?p=207

Antonio Bakula
  • 20,445
  • 6
  • 75
  • 102