We have some global keyboard hooks installed via SetWindowsHookEx with WH_KEYBOARD_LL that appear to randomly get unhooked by Windows.
We
Very late but thought i'd share something. Gathering from here there's a couple hints like putting the SetWindowsHookEx in a separate thread and that it's more a scheduling problem.
I also noticed that Application.DoEvents was using quite a bit of CPU, and found that PeekMessage uses less.
public static bool active = true;
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool PeekMessage(out NativeMessage message,
IntPtr handle, uint filterMin, uint filterMax, uint flags);
public const int PM_NOREMOVE = 0;
public const int PM_REMOVE = 0x0001;
protected void MouseHooker()
{
NativeMessage msg;
using (Process curProcess = Process.GetCurrentProcess())
{
using (ProcessModule curModule = curProcess.MainModule)
{
// Install the low level mouse hook that will put events into _mouseEvents
_hookproc = MouseHookCallback;
_hookId = User32.SetWindowsHookEx(WH.WH_MOUSE_LL, _hookproc, Kernel32.GetModuleHandle(curModule.ModuleName), 0);
}
}
while (active)
{
while (PeekMessage(out msg, IntPtr.Zero,
(uint)WM.WM_MOUSEFIRST, (uint)WM.WM_MOUSELAST, PM_NOREMOVE))
;
Thread.Sleep(10);
}
User32.UnhookWindowsHookEx(_hookId);
_hookId = IntPtr.Zero;
}
public void HookMouse()
{
active = true;
if (_hookId == IntPtr.Zero)
{
_mouseHookThread = new Thread(MouseHooker);
_mouseHookThread.IsBackground = true;
_mouseHookThread.Priority = ThreadPriority.Highest;
_mouseHookThread.Start();
}
}
so just change the active bool to false in Deactivate event and call HookMouse in the Activated event.
HTH
EDIT: I noticed games were slowed down with this, so decided to unhook when app is not active using Activated and Deactivate events.