I need to write an application which globally intercepts Alt+Shift+S.

What I did is I created a DLL which sets global hooks:

namespace Hotkeydll
{
    public class MyHotKey
    {
        public static void setHooks()
        {
            KeyboardHookProcedure = new HookProc(KeyboardHookProc);
            hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
        }

        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
        	//write something into file
        }
   }
}

Then I created a program which loads this DLL and set the hook:

using Hotkeydll;
namespace IWFHotkeyStarter
{
    class Program
    {
        static void Main(string[] args)
        {
            MyHotKey.setHooks();
        }
    }
}

Now the problem is that the hotkey doesn't work.

It looks like the DLL is not loaded permanently into memory. I see that I can delete the dll file from file system.

So please advise what I am doing wrong?

Should I use a different approach?

Thank you.

if all you need is a simple hotkey combination, why even go the route of a low level keyboard hook? Windows has a HotKey api for this very situation.

Here is a simple but usable rewrite of some code I hacked up for one of my projects

//API Imports
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(
            IntPtr hWnd, // handle to window    
            int id, // hot key identifier    
            KeyModifiers fsModifiers, // key-modifier options    
            Keys vk    // virtual-key code    
            );

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(
            IntPtr hWnd, // handle to window    
            int id      // hot key identifier    
            );

        const int HOTKEY_ID = 31197; //Any number to use to identify the hotkey instance

        public enum KeyModifiers        //enum to call 3rd parameter of RegisterHotKey easily
        {
            None = 0,
            Alt = 1,
            Control = 2,
            Shift = 4,
            Windows = 8
        }
        
        public bool setHotKey(KeyModifiers Kmds, Keys key)
        {
            return RegisterHotKey(this.Handle, HOTKEY_ID, Kmds, key);
        }

        public bool unSetHotKey()
        {
            return UnregisterHotKey(this.Handle, HOTKEY_ID);
        }

        const int WM_HOTKEY = 0x0312;//magic hotkey message identifier

        protected override void WndProc(ref Message message)
        {
            switch (message.Msg)
            {
                case WM_HOTKEY:
                    Keys key = (Keys)(((int)message.LParam >> 16) & 0xFFFF);
                    KeyModifiers modifier = (KeyModifiers)((int)message.LParam & 0xFFFF);

                    //put your on hotkey code here
                    MessageBox.Show("HotKey Pressed :" + modifier.ToString() + " " + key.ToString());
                    //end hotkey code

                    break;

            }
            base.WndProc(ref message);
        }

        //put this code in the onload method of your form
           setHotKey(KeyModifiers.Alt | KeyModifiers.Shift, Keys.S);

        //and set up a form closed event and call
            unSetHotKey();

This can actually be shoved into a child class, but that gets complicated as you have to use a nativewindow class to capture the wndproc and of course if you need more than one hotkey then you have to filter through the combination in wndproc, the easiest way to that would be to create a hotkey object and compare keymodifiers and keys against them. But this is a simplified version. (it still has all the groundwork for a multi hotkey implementation.) best of luck.

Comments
Perfect!
This article has been dead for over six months. Start a new discussion instead.