Setting up system-wide hot keys

You can see examples of global system-wide hot keys almost in every application: media players, chats, different tray tools, etc. The application can be minimized or even hidden, but you can control it by pressing hot keys no matter what is in focus right now.

Unfortunately, .NET Framework doesn’t contain convenient classes or methods for setting up global system-wide hot keys. The only way to achieve this is to use Windows API functions.

To simplify registering, unregistering hot keys in the system and reacting on their pressings, I’ve created a small library GlobalHotKey. It provides an easy way to work with system-wide hot keys by wrapping calls of native functions. Internally it uses Windows API RegisterHotKey and UnregisterHotKey functions and hides all interaction with them from you.

An example code how to use GlobalHotKey:

using System.Windows.Input;
using GlobalHotKey;
// ...
hotKeyManager = new HotKeyManager();
hotKeyManager.KeyPressed += HotKeyManagerPressed;
// ...
void HotKeyManagerPressed(object sender, KeyPressedEventArgs e)
{
    if (e.HotKey.Key == Key.F5)
        MessageBox.Show("Hot key pressed!");
}
// ...
// Register Ctrl+Alt+F5
var hotKey = hotKeyManager.Register(Key.F5, ModifierKeys.Control | ModifierKeys.Alt);
// Unregister Ctrl+Alt+F5
hotKeyManager.Unregister(hotKey);
// ...
hotKeyManager.Dispose();

HotKeyManager class registers and unregisters system-wide hot keys, handles them, and raises event on hot keys pressing.
KeyPressedEventArgs class contains information about pressed hot key and keys modifiers.
Note also, that you don’t need to unregister all hot keys manually before disposing, because Dispose() does it.

The source code is available on GitHub.
On the Downloads page you can find already compiled assembly ready to use in your application.
You can also install it in your application using NuGet:
PM> Install-Package GlobalHotKey

6 thoughts on “Setting up system-wide hot keys

  1. This looks like a really handy tool, but in a simple console application test it failed to trigger any of the hotkeys… is this only for GUIs..? Sorry if I’m missing something obvious, amateur in C#.

    Here was my code:

    [STAThread]
    static void Main(string[] args)
    {
    HotKeyManager hotKeyManager = new HotKeyManager();
    hotKeyManager.KeyPressed += new EventHandler(hotKeyManager_KeyPressed);

    //Create and register a hotkey using the HotKey class
    HotKey hotkeyA = new HotKey(Key.A, ModifierKeys.None);
    hotKeyManager.Register(hotkeyA);

    //Pause for hotkeys
    Console.ReadLine();
    }

    //This never gets activated
    static void hotKeyManager_KeyPressed(object sender, KeyPressedEventArgs e)
    {
    Console.WriteLine(“A hotkey has been pressed! This runs any time a registered hotkey is pressed!”);

    if (e.HotKey.Key == Key.A)
    {
    Console.WriteLine(“You pressed ‘A’ with no modifiers!”);
    }
    }

    1. Console application has only one thread. Thats why your application doesn’t receives any events from keys pressing. You should wait for events in a separate thread.

      1. Ahh, that makes sense.

        I tried creating a threaded version for a console application using:
        HotkeyManager hotkeyManager = new HotkeyManager();

        Thread keyListener = new Thread(new ThreadStart(hotkeyManager.Run));
        keyListener.SetApartmentState(ApartmentState.STA);
        keyListener.Start();

        …where the HotkeyManager, when run, registers a hotkey and prints out that it is running:

        public void Run()
        {
        CreateKeyListeners();

        while (true)
        {
        Console.WriteLine(“HotKey Manager thread.”);
        Thread.Sleep(10000);
        }

        }

        private void CreateKeyListeners()
        {
        manager.KeyPressed += new EventHandler(hotKeyManager_KeyPressed);

        //Test to see if an almost-definitely-unregistered hotkey is still unavailable for registration
        var uncommonHotkey = manager.Register(Key.Space, ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift | ModifierKeys.Windows);
        }

        This gives me a Win32Exception: “Can’t register the hotkey” regardless of what hotkey I try to register. Any idea why this might be?

  2. Internally HotKeyManager just calls Win32 API function RegisterHotKey (you can view the source code on GitHub). Please, refer to the MSDN to find out the cause of an exception.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s