locked
Tracking KeyPress event using Windows Service RRS feed

  • Question

  • Could u tell me how to track keypress event in windows service

     

    Wednesday, July 14, 2010 5:56 AM

Answers

  • Hi Phani25485,

    I made a class named KeyHook which will catch all the key press event of keyboard, it provides three global event :OnKeyDownEvent、OnKeyUpEvent、 OnKeyPressEvent, and two methods: Start() and Stop() to start and stop the tracking.

    Class KeyHook:
        public class KeyBordHook
        {
            private const int WM_KEYDOWN = 0x100;
            private const int WM_KEYUP = 0x101;
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;

            //Global event 
            public event KeyEventHandler OnKeyDownEvent;
            public event KeyEventHandler OnKeyUpEvent;
            public event KeyPressEventHandler OnKeyPressEvent;

            static int hKeyboardHook = 0; 
         
            public const int WH_KEYBOARD_LL = 13; //keyboard hook constant

            HookProc KeyboardHookProcedure; // declare keyhook event type

            //declare keyhook struct 
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode;   
                public int scanCode;   
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
              
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

            [DllImport("user32")]
            public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);

            [DllImport("user32")]
            public static extern int GetKeyboardState(byte[] pbKeyState);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto,
    CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);

            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

            public List<Keys> preKeys = new List<Keys>();

      
            public KeyBordHook()
            {
                Start();
            }

             ~KeyBordHook()
            {
                Stop();
            }

            public void Start()
            {
                //install keyboard hook 
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                    Process curProcess = Process.GetCurrentProcess();
                    ProcessModule curModule = curProcess.MainModule;

                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);

                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("SetWindowsHookEx ist failed.");
                    }
                }
            }

            public void Stop()
            {
                bool retKeyboard = true;

                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                //if unhook failed 
                if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
            }

            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {

                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                                       
                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)
                        {
                            preKeys.Add(keyData);
                        }
                    }
                    
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));

                        OnKeyDownEvent(this, e);
                    }

                    if (OnKeyPressEvent != null && wParam == WM_KEYDOWN)
                    {
                        byte[] keyState = new byte[256];
                        GetKeyboardState(keyState);

                        byte[] inBuffer = new byte[2];
                        if (ToAscii(MyKeyboardHookStruct.vkCode,
                        MyKeyboardHookStruct.scanCode,
                        keyState,
                        inBuffer,
                        MyKeyboardHookStruct.flags) == 1)
                        {
                            KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                            OnKeyPressEvent(this, e);
                        }
                    }

                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData))
                        {

                            for (int i = preKeys.Count - 1; i >= 0; i--)
                            {
                                if (preKeys[i] == keyData)
                                {
                                    preKeys.RemoveAt(i);
                                }
                            }

                        }
                    }
                   
                    if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
                        OnKeyUpEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }

            private Keys GetDownKeys(Keys key)
            {
                Keys rtnKey = Keys.None;
                foreach (Keys keyTemp in preKeys)
                {
                    switch (keyTemp)
                    {
                        case Keys.LControlKey:
                        case Keys.RControlKey:
                            rtnKey = rtnKey | Keys.Control;
                            break;
                        case Keys.LMenu:
                        case Keys.RMenu:
                            rtnKey = rtnKey | Keys.Alt;
                            break;
                        case Keys.LShiftKey:
                        case Keys.RShiftKey:
                            rtnKey = rtnKey | Keys.Shift;
                            break;
                        default:
                            break;
                    }
                }
                rtnKey = rtnKey | key;

                return rtnKey;
            }

            private Boolean IsCtrlAltShiftKeys(Keys key)
            {

                switch (key)
                {
                    case Keys.LControlKey:
                    case Keys.RControlKey:
                    case Keys.LMenu:
                    case Keys.RMenu:
                    case Keys.LShiftKey:
                    case Keys.RShiftKey:
                        return true;
                    default:
                        return false;
                }
            }
        }

    And then in the background form, here I used a listbox named lbSpy to show/check what key did I pressed. Knowing this you can make use of the showed result in the lbSpy, including simply count how many time the Enter key (or any other keys you interested )had been pressed. (with respect to Enter key, the key code "return" will show in the listbox lbSpy)

    Code snippet in form FrmSpy:

     public partial class FrmSpy : Form
        {
            KeyBordHook _KeyBordHook = new KeyBordHook();

            public FrmSpy()
            {
                InitializeComponent();
            }

            private void FrmSpy_Load(object sender, EventArgs e)
            {
                _KeyBordHook.OnKeyDownEvent += new KeyEventHandler(_KeyBordHook_OnKeyDownEvent);

                _KeyBordHook.OnKeyPressEvent += new KeyPressEventHandler(_KeyBordHook_OnKeyPressEvent);

                _KeyBordHook.OnKeyUpEvent += new KeyEventHandler(_KeyBordHook_OnKeyUpEvent);

                _KeyBordHook.Start();
            }

            void _KeyBordHook_OnKeyUpEvent(object sender, KeyEventArgs e)
            {
                lbSpy.Items.Add(e.KeyCode.ToString());
            }

            void _KeyBordHook_OnKeyPressEvent(object sender, KeyPressEventArgs e)
            {
               
            }

            void _KeyBordHook_OnKeyDownEvent(object sender, KeyEventArgs e)
            {
            }

            private void FrmSpy_FormClosed(object sender, FormClosedEventArgs e)
            {
                _KeyBordHook.Stop();
            }
        }


    Best Wishes,
    Helen Zhou


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    • Marked as answer by Helen Zhou Wednesday, July 21, 2010 12:53 AM
    Monday, July 19, 2010 1:34 PM

All replies

  • I mean i want to track  the keypress event from keyboard keys not any controls,

    could u please tell me how to do that

    Wednesday, July 14, 2010 6:00 AM
  • Hello Phani,

         You cannot handle the keypress event in windows service. Moreover, kindly find below the understanding on the same:

           Windows services are processes that run in the background, without a user interface, and in their own user session. Services can be automatically started when the computer starts, even if a user does not log on. Therefore, services are an ideal way to implement an application that should be running constantly and does not need to interact with the user.

           Can you please tell why you want to handle KeyPress Event in Windows Service and what is the purpose of the same ?

     

    Thanks,

    Paras Sanghani

    Mark As Answer if it helped you.

    Wednesday, July 14, 2010 6:15 AM
  • Hi,

          I want to track the number of times i pressed the Enter Key irrespective of

          how many application I opened and did some work, on the background i want a counter that shows the

          count of number of times enter key is pressed

    Wednesday, July 14, 2010 7:04 AM
  • Hi Phani25485,

    I made a class named KeyHook which will catch all the key press event of keyboard, it provides three global event :OnKeyDownEvent、OnKeyUpEvent、 OnKeyPressEvent, and two methods: Start() and Stop() to start and stop the tracking.

    Class KeyHook:
        public class KeyBordHook
        {
            private const int WM_KEYDOWN = 0x100;
            private const int WM_KEYUP = 0x101;
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;

            //Global event 
            public event KeyEventHandler OnKeyDownEvent;
            public event KeyEventHandler OnKeyUpEvent;
            public event KeyPressEventHandler OnKeyPressEvent;

            static int hKeyboardHook = 0; 
         
            public const int WH_KEYBOARD_LL = 13; //keyboard hook constant

            HookProc KeyboardHookProcedure; // declare keyhook event type

            //declare keyhook struct 
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode;   
                public int scanCode;   
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
              
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);

            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

            [DllImport("user32")]
            public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);

            [DllImport("user32")]
            public static extern int GetKeyboardState(byte[] pbKeyState);

            [DllImport("kernel32.dll", CharSet = CharSet.Auto,
    CallingConvention = CallingConvention.StdCall)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);

            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

            public List<Keys> preKeys = new List<Keys>();

      
            public KeyBordHook()
            {
                Start();
            }

             ~KeyBordHook()
            {
                Stop();
            }

            public void Start()
            {
                //install keyboard hook 
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                    Process curProcess = Process.GetCurrentProcess();
                    ProcessModule curModule = curProcess.MainModule;

                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);

                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("SetWindowsHookEx ist failed.");
                    }
                }
            }

            public void Stop()
            {
                bool retKeyboard = true;

                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                //if unhook failed 
                if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
            }

            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {

                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                                       
                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)
                        {
                            preKeys.Add(keyData);
                        }
                    }
                    
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));

                        OnKeyDownEvent(this, e);
                    }

                    if (OnKeyPressEvent != null && wParam == WM_KEYDOWN)
                    {
                        byte[] keyState = new byte[256];
                        GetKeyboardState(keyState);

                        byte[] inBuffer = new byte[2];
                        if (ToAscii(MyKeyboardHookStruct.vkCode,
                        MyKeyboardHookStruct.scanCode,
                        keyState,
                        inBuffer,
                        MyKeyboardHookStruct.flags) == 1)
                        {
                            KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                            OnKeyPressEvent(this, e);
                        }
                    }

                    if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        if (IsCtrlAltShiftKeys(keyData))
                        {

                            for (int i = preKeys.Count - 1; i >= 0; i--)
                            {
                                if (preKeys[i] == keyData)
                                {
                                    preKeys.RemoveAt(i);
                                }
                            }

                        }
                    }
                   
                    if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                    {
                        Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
                        OnKeyUpEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }

            private Keys GetDownKeys(Keys key)
            {
                Keys rtnKey = Keys.None;
                foreach (Keys keyTemp in preKeys)
                {
                    switch (keyTemp)
                    {
                        case Keys.LControlKey:
                        case Keys.RControlKey:
                            rtnKey = rtnKey | Keys.Control;
                            break;
                        case Keys.LMenu:
                        case Keys.RMenu:
                            rtnKey = rtnKey | Keys.Alt;
                            break;
                        case Keys.LShiftKey:
                        case Keys.RShiftKey:
                            rtnKey = rtnKey | Keys.Shift;
                            break;
                        default:
                            break;
                    }
                }
                rtnKey = rtnKey | key;

                return rtnKey;
            }

            private Boolean IsCtrlAltShiftKeys(Keys key)
            {

                switch (key)
                {
                    case Keys.LControlKey:
                    case Keys.RControlKey:
                    case Keys.LMenu:
                    case Keys.RMenu:
                    case Keys.LShiftKey:
                    case Keys.RShiftKey:
                        return true;
                    default:
                        return false;
                }
            }
        }

    And then in the background form, here I used a listbox named lbSpy to show/check what key did I pressed. Knowing this you can make use of the showed result in the lbSpy, including simply count how many time the Enter key (or any other keys you interested )had been pressed. (with respect to Enter key, the key code "return" will show in the listbox lbSpy)

    Code snippet in form FrmSpy:

     public partial class FrmSpy : Form
        {
            KeyBordHook _KeyBordHook = new KeyBordHook();

            public FrmSpy()
            {
                InitializeComponent();
            }

            private void FrmSpy_Load(object sender, EventArgs e)
            {
                _KeyBordHook.OnKeyDownEvent += new KeyEventHandler(_KeyBordHook_OnKeyDownEvent);

                _KeyBordHook.OnKeyPressEvent += new KeyPressEventHandler(_KeyBordHook_OnKeyPressEvent);

                _KeyBordHook.OnKeyUpEvent += new KeyEventHandler(_KeyBordHook_OnKeyUpEvent);

                _KeyBordHook.Start();
            }

            void _KeyBordHook_OnKeyUpEvent(object sender, KeyEventArgs e)
            {
                lbSpy.Items.Add(e.KeyCode.ToString());
            }

            void _KeyBordHook_OnKeyPressEvent(object sender, KeyPressEventArgs e)
            {
               
            }

            void _KeyBordHook_OnKeyDownEvent(object sender, KeyEventArgs e)
            {
            }

            private void FrmSpy_FormClosed(object sender, FormClosedEventArgs e)
            {
                _KeyBordHook.Stop();
            }
        }


    Best Wishes,
    Helen Zhou


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    • Marked as answer by Helen Zhou Wednesday, July 21, 2010 12:53 AM
    Monday, July 19, 2010 1:34 PM
  • I can tell you why I would want to do it, I have a system that I need to talk to based on a few keys from the KeyBoard. I do not want an application that a user can close down ie stop from running, I do not want an application that can be easily prevented from running - i.e in the startup automatic startup. I want a plain jane computer not much security involved and to simply start the service capture the codes and transmit the info I want to send according to the Key Press!

    Friday, January 10, 2014 3:26 PM
  • Could u tell me how to track keypress event in windows service

     

    hi,

    I need to create a windows services which need to monitor background process in a machine, especially adobe opened in a machine with Ctrl +L key pressed and Long key press(same key continuously). 

    The above said items prevents a machine go to sleep. Could you peoples help me to sort out this?

    Tuesday, July 3, 2018 7:00 AM