0

I am recording user actions for a study (people taking part of the study are aware that their actions are recorded), therefore I have been building a little keylogger in C#.

Thanks to msdn doc and some tutorial I could make something work quite well with KeyPressEvent, but now I realized 5 days ago that I have trouble with the ctrl, alt modifiers. I figured out that I had to use KeyDown and KeyUp events to record theses.

Here are my windows form code and my KeyProc function located in Hook.cs class:

private IntPtr KeyProc(int nCode, int wParam, IntPtr lParam)
    {
        bool handled = false;
        //On verifie si tous est ok
        if ((nCode >= 0) && (m_onKeyDown != null || m_onKeyUp != null || m_onKeyPress != null))
        {
            KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
            //KeyDown


            if (m_onKeyDown != null && (wParam == 0x100 || wParam == 0x104))
            {
                Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                KeyEventArgs e = new KeyEventArgs(keyData);
                m_onKeyDown(this, e);
                handled = handled || e.Handled;
            }

            // KeyPress
            if (m_onKeyPress != null && wParam == 0x100)
            {
                bool isShift = ((GetKeyState(0x10) & 0x80) == 0x80 ? true : false);
                bool isCapslock = (GetKeyState(0x14) != 0 ? true : false);

                //bool isCtrl = (GetKeyState(0x11) != 0 ? true : false);
                //bool isAlt = (GetKeyState(0x12) != 0 ? true : false);

                byte[] keyState = new byte[256];
                GetKeyboardState(keyState);
                byte[] inBuffer = new byte[2];
                if (ToAscii(MyKeyboardHookStruct.vkCode,
                          MyKeyboardHookStruct.scanCode,
                          keyState,
                          inBuffer,
                          MyKeyboardHookStruct.flags) == 1)
                {
                    char key = (char)inBuffer[0];
                    if ((isCapslock ^ isShift) && Char.IsLetter(key))
                        key = Char.ToUpper(key);

                    KeyPressEventArgs e = new KeyPressEventArgs(key);
                    m_onKeyPress(this, e);
                    handled = handled || e.Handled;
                }
            }

            // KeyUp
            if (m_onKeyUp != null && (wParam == 0x101 || wParam == 0x105))
            {
                Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                KeyEventArgs e = new KeyEventArgs(keyData);
                m_onKeyUp(this, e);
                handled = handled || e.Handled;
            }
        }

private void OnKeyUp(object sender, KeyEventArgs e)
    {
        if (e.Control)
            flagD = false;
    }

    private void OnKeyDown(object sender, KeyEventArgs e)
    {
        textBox1.Text += e.KeyCode;
        flagD = e.Control ? true : false;
        textBox1.Text += " " + flagD;    
    }

I don't understand why e.Control is always false, I have been featuring e.KeyCode in a textbox; I can see that the ControlKey is recorded but I don't understand why the flagD is always false.

Andrew
  • 4,953
  • 15
  • 40
  • 58
vbvx
  • 609
  • 7
  • 22
  • Because you forgot to include them in *keyData*. Like `if (isCtrl) keyData |= Keys.Control;` Do keep in mind that this cannot be accurate when the key was pressed when another process had the focus. Keyboard state is a per-thread property. ToAscii() cannot be accurate either for the same reason. Doing this correctly requires a WH_KEYBOARD hook, can't write those in C#. – Hans Passant Sep 18 '14 at 14:33
  • thx for the answer, I didnt know how to change the attribute that was the main problem. Actually for thoses who care, I used a system of flag for every non system key. I map evereything in a class Flags.cs and I update the flag calling the adequate methods from Flag.cs in KeyUp / KeyDown events (eg: ctrl is pressed, OnKeyDown event is raised flag.Ctrl->1 ; ctrl is realeased, OnkeyUp is raised flag=0) @Hans I don't know if I understand you well, but I am using a Global Hook, low-level Hook for KeyBoard and Mouse don't need special dll. It's working even when the window doesn't have focus. – vbvx Sep 19 '14 at 14:56

0 Answers0