My application should perform some action whenever user pressed certain keys in windows.
Calling SetWindowsHookEx
with WH_KEYBOARD_LL
option seems to be standard way to achieve this. However in my case something is clearly wrong and callback in not fired.
Main method of my debugging console application:
static void Main(string[] args)
{
IntPtr moduleHandle = GetCurrentModuleHandle();
IntPtr hookHandle = IntPtr.Zero;
try
{
User32.HookProc hook = (nCode, wParam, lParam) =>
{
// code is never called :-(
if (nCode >= 0)
{
Console.WriteLine("{0}, {1}", wParam.ToInt32(), lParam.ToInt32());
}
return User32.CallNextHookEx(hookHandle, nCode, wParam, lParam);
};
hookHandle = User32.SetWindowsHookEx(User32.WH_KEYBOARD_LL, hook, moduleHandle, 0);
Console.ReadLine(); //
}
finally
{
if (hoodHandle != IntPtr.Zero)
{
var unhooked = User32.UnhookWindowsHookEx(hookHandle);
Console.WriteLine(unhooked); // true
hookHandle = IntPtr.Zero;
}
}
}
GetCurrentModuleHandle method:
private static IntPtr GetCurrentModuleHandle()
{
using (var currentProcess = Process.GetCurrentProcess())
using (var mainModule = currentProcess.MainModule)
{
var moduleName = mainModule.ModuleName;
return Kernel32.GetModuleHandle(moduleName);
}
}
Imports from user32.dll
and kernel32.dll
:
public static class User32
{
public const int WH_KEYBOARD_LL = 13;
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
}
public static class Kernel32
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
}
Do you have any idea what I is my problem?