Global mouse event handler

return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);

This code will fail when you run it on .NET 4 on a Windows version earlier than Windows 8. The CLR no longer simulates unmanaged module handles for managed assemblies. You can’t detect this failure in your code because it is missing the required error checking. Both on GetModuleHandle and SetWindowsHookEx. Never skip error checking when you pinvoke, the winapi doesn’t throw exceptions. Check if they return IntPtr.Zero and simply throw a Win32Exception when they do.

The fix is simple, SetWindowsHookEx() requires a valid module handle but doesn’t actually use it when you set a low-level mouse hook. So any handle will do, you can pass the handle for user32.dll, always loaded in a .NET application. Fix:

IntPtr hook = SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle("user32"), 0);
if (hook == IntPtr.Zero) 
{
    throw new System.ComponentModel.Win32Exception();
}
return hook;

Leave a Comment