Skip to content

Instantly share code, notes, and snippets.

@Stasonix
Created July 26, 2012 08:52
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save Stasonix/3181083 to your computer and use it in GitHub Desktop.
Save Stasonix/3181083 to your computer and use it in GitHub Desktop.
GLOBAL HOOK example C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace WFA
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// ... { GLOBAL HOOK }
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
const int WH_KEYBOARD_LL = 13; // Номер глобального LowLevel-хука на клавиатуру
const int WM_KEYDOWN = 0x100; // Сообщения нажатия клавиши
private LowLevelKeyboardProc _proc = hookProc;
private static IntPtr hhook = IntPtr.Zero;
public void SetHook()
{
IntPtr hInstance = LoadLibrary("User32");
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
}
public static void UnHook()
{
UnhookWindowsHookEx(hhook);
}
public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
//////ОБРАБОТКА НАЖАТИЯ
if (vkCode.ToString() == "162")
{
MessageBox.Show("You pressed a CTR");
}
return (IntPtr)1;
}
else
return CallNextHookEx(hhook, code, (int)wParam, lParam);
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// убираем хук
UnHook();
}
private void Form1_Load(object sender, EventArgs e)
{
// Устанавливаем хук
SetHook();
}
}
}
@Stasonix
Copy link
Author

CTR key hook which calls MessageBox.Show("You pressed a CTR") dialog.

@kR105-zz
Copy link

You can also use:
Keys k = (Keys)Marshal.ReadInt32(lParam);

@zhonghh13
Copy link

why use LoadLibrary("User32")? does it possible hook other application's editing event, like WM_SETTEXT message?

@jddavies89
Copy link

Thanks for the how to, its very good but there is a problem that i cant figure out.

Say i open notepad and type 'abc' in, it gets written to the StreamWriter but not in notepad.

Does anyone have any ideas?

thank you, this is the code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CaptainHook
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

    // ... { GLOBAL HOOK }
    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    [DllImport("user32.dll")]
    static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    const int WH_KEYBOARD_LL = 13; // Номер глобального LowLevel-хука на клавиатуру
    const int WM_KEYDOWN = 0x100; // Сообщения нажатия клавиши

    private LowLevelKeyboardProc _proc = hookProc;

    private static IntPtr hhook = IntPtr.Zero;

    public void SetHook()
    {
        IntPtr hInstance = LoadLibrary("User32");
        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
    }

    public static void UnHook()
    {
        UnhookWindowsHookEx(hhook);
    }

    public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
          int vkCode = Marshal.ReadInt32(lParam);
            string dT = DateTime.Now.Day +" "+ DateTime.Now.Month.ToString() +" "+ DateTime.Now.Year.ToString();
            using (StreamWriter sw = new StreamWriter(@"C:\Keys\key"+dT +".txt", append:true))
            {
                //https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
                //United Kingdom Keyboard layout.
              //  if (vkCode.ToString() == "17")
                    if (vkCode.ToString() == "17")
                    {
                        // MessageBox.Show("You pressed a CTR");
                        // Write each directory name to a file.
                        sw.Write("CTRL");

                }
                else if (vkCode.ToString() == "91")
                {
                    sw.Write("LEFT WINDOW");
                }
                else if (vkCode.ToString() == "18")
                {
                    sw.Write("ALT");
                }
                else if (vkCode.ToString() == "32")
                {
                    sw.Write("SPACE BAR");
                }
                else if (vkCode.ToString() == "92")
                {
                    sw.Write("RIGHT WINDOW");
                    MessageBox.Show("Right Window");
                }
                else if (vkCode.ToString() == "93")
                {
                    sw.Write("SELECT KEY");
                }
                else if (vkCode.ToString() == "16")
                {
                    sw.Write("SHIFT");
                }
                else if (vkCode.ToString() == "20")
                {
                    sw.Write("CAPS LOCK");
                }
                else if (vkCode.ToString() == "9")
                {
                    sw.Write("TAB");
                }
                else if (vkCode.ToString() == "13")
                {
                    sw.Write("ENTER");
                }
                else if (vkCode.ToString() == "8")
                {
                    sw.Write("BACK SPACE");
                }
                else if (vkCode.ToString() == "187")
                {
                    sw.Write("=");
                }
                else if (vkCode.ToString() == "189")
                {
                    sw.Write("-");
                }
                else if (vkCode.ToString() == "27")
                {
                    sw.Write("ESC");
                }
                else if (vkCode.ToString() == "45")
                {
                    sw.Write("INSERT");
                }
                else if (vkCode.ToString() == "46")
                {
                    sw.Write("DELETE");
                }
                else if (vkCode.ToString() == "36")
                {
                    sw.Write("HOME");
                }
                else if (vkCode.ToString() == "35")
                {
                    sw.Write("END");
                }
                else if (vkCode.ToString() == "33")
                {
                    sw.Write("PAGE UP");
                }
                else if (vkCode.ToString() == "34")
                {
                    sw.Write("PAGE DOWN");
                }
                else if (vkCode.ToString() == "114")
                {
                    sw.Write("NUMBER LOCK");
                }
                else if (vkCode.ToString() == "111")
                {
                    sw.Write("DIVIDE");
                }
                else if (vkCode.ToString() == "106")
                {
                    sw.Write("MULTIPLY");
                }
                else if (vkCode.ToString() == "109")
                {
                    sw.Write("SUBTRACK");
                }
                else if (vkCode.ToString() == "107")
                {
                    sw.Write("ADD");
                }
                else if (vkCode.ToString() == "145")
                {
                    sw.Write("SCROLL LOCK");
                }
                else if (vkCode.ToString() == "19")
                {
                    sw.Write("PAUSE/BREAK");
                }
                else if (vkCode.ToString() == "112")
                {
                    sw.Write("F1");
                }
                else if (vkCode.ToString() == "113")
                {
                    sw.Write("F2");
                }
                else if (vkCode.ToString() == "114")
                {
                    sw.Write("F3");
                }
                else if (vkCode.ToString() == "115")
                {
                    sw.Write("F4");
                }
                else if (vkCode.ToString() == "116")
                {
                    sw.Write("F5");
                }
                else if (vkCode.ToString() == "117")
                {
                    sw.Write("F6");
                }
                else if (vkCode.ToString() == "118")
                {
                    sw.Write("F7");
                }
                else if (vkCode.ToString() == "119")
                {
                    sw.Write("F8");
                }
                else if (vkCode.ToString() == "120")
                {
                    sw.Write("F9");
                }
                else if (vkCode.ToString() == "121")
                {
                    sw.Write("F10");
                }
                else if (vkCode.ToString() == "122")
                {
                    sw.Write("F11");
                }
                else if (vkCode.ToString() == "123")
                {
                    sw.Write("F12");
                }
                else if (vkCode.ToString() == "188")
                {
                    sw.Write(",");
                }
                else if (vkCode.ToString() == "190")
                {
                    sw.Write(".");
                }
                else if (vkCode.ToString() == "191")
                {
                    sw.Write("/");
                }
                else if (vkCode.ToString() == "220")
                {
                    sw.Write(@"\");
                }
                else if (vkCode.ToString() == "192")
                {
                    sw.Write("'");
                }
                else if (vkCode.ToString() == "65")
                {
                    sw.Write("A");
                }
                else if (vkCode.ToString() == "66")
                {
                    sw.Write("B");
                }
                else if (vkCode.ToString() == "67")
                {
                    sw.Write("C");
                }
                else if (vkCode.ToString() == "68")
                {
                    sw.Write("D");
                }
                else if (vkCode.ToString() == "69")
                {
                    sw.Write("E");
                }
                else if (vkCode.ToString() == "70")
                {
                    sw.Write("F");
                }
                else if (vkCode.ToString() == "71")
                {
                    sw.Write("G");
                }
                else if (vkCode.ToString() == "72")
                {
                    sw.Write("H");
                }
                else if (vkCode.ToString() == "73")
                {
                    sw.Write("I");
                }
                else if (vkCode.ToString() == "74")
                {
                    sw.Write("J");
                }
                else if (vkCode.ToString() == "75")
                {
                    sw.Write("K");
                }
                else if (vkCode.ToString() == "76")
                {
                    sw.Write("L");
                }
                else if (vkCode.ToString() == "77")
                {
                    sw.Write("M");
                }
                else if (vkCode.ToString() == "78")
                {
                    sw.Write("N");
                }
                else if (vkCode.ToString() == "79")
                {
                    sw.Write("O");
                }
                else if (vkCode.ToString() == "80")
                {
                    sw.Write("P");
                }
                else if (vkCode.ToString() == "81")
                {
                    sw.Write("Q");
                }
                else if (vkCode.ToString() == "82")
                {
                    sw.Write("R");
                }
                else if (vkCode.ToString() == "83")
                {
                    sw.Write("S");
                }
                else if (vkCode.ToString() == "84")
                {
                    sw.Write("T");
                }
                else if (vkCode.ToString() == "85")
                {
                    sw.Write("U");
                }
                else if (vkCode.ToString() == "86")
                {
                    sw.Write("V");
                }
                else if (vkCode.ToString() == "87")
                {
                    sw.Write("W");
                }
                else if (vkCode.ToString() == "88")
                {
                    sw.Write("X");
                }
                else if (vkCode.ToString() == "89")
                {
                    sw.Write("Y");
                }
                else if (vkCode.ToString() == "90")
                {
                    sw.Write("Z");
                }
                else if (vkCode.ToString() == "96")
                {
                    sw.Write("numpad 0");
                }
                else if (vkCode.ToString() == "97")
                {
                    sw.Write("numpad 1");
                }
                else if (vkCode.ToString() == "98")
                {
                    sw.Write("numpad 2");
                }
                else if (vkCode.ToString() == "99")
                {
                    sw.Write("numpad 3");
                }
                else if (vkCode.ToString() == "100")
                {
                    sw.Write("numpad 4");
                }
                else if (vkCode.ToString() == "101")
                {
                    sw.Write("numpad 5");
                }
                else if (vkCode.ToString() == "102")
                {
                    sw.Write("numpad 6");
                }
                else if (vkCode.ToString() == "103")
                {
                    sw.Write("numpad 7");
                }
                else if (vkCode.ToString() == "104")
                {
                    sw.Write("numpad 8");
                }
                else if (vkCode.ToString() == "105")
                {
                    sw.Write("numpad 9");
                }
                sw.Close();
            }

            return (IntPtr)1;         
        }
        else
            return CallNextHookEx(hhook, code, (int)wParam, lParam);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        SetHook();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        UnHook();
    }

}

}

@L0rdKlappstuhl
Copy link

@Joer89 You are not calling CallNextHookEx in case you find the strings you are writing to your stream you return before that...
You should always call CallNextHookEx. And btw... please use a switch case instead of if /else cascades...

@MrLolthe1st
Copy link

Thanks! 1st of one hundred not working hook examples.

@hoangdao1968
Copy link

What a great example, however I cannot hook lower case characters. Can you help me?

@shmelrad
Copy link

Во время выполнения программы нельзя печатать( что делать?

@romagny13
Copy link

Great. Thanks

@MyelinsheathXD
Copy link

Wohh , thx! finally found!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment