Search code examples
c#hooksetwindowshookex.net-4.8mousekeyhook

Windows Hooks do not trigger events and windows starts lagging. (Using globalmousekeyhook in C#)


I currently work with the Steelseries GameSense SDK to make my own effects etc. for my keyboard and mouse.

To light up my mouse and keyboard on clicks and presses, I use the globalmousekeyhook library.

Unfortunately, the mouse and keyboard events don't get triggered.

Also, my mouse starts lagging, and keyboard input gets delayed.

The lag and the delay only stay for about half a minute.

I suspect that windows removes the hooks because it detects the lag.

I also tried this example program and everything works fine there.

Here is the code:

private static readonly IKeyboardMouseEvents GlobalHook = Hook.GlobalEvents();
static InputManager()
{
    Logger.Log("Starting...", Logger.Type.Info);
    GlobalHook.KeyDown += KeyEvent;
    GlobalHook.MouseDownExt += MouseEvent;
    Logger.Log("Ready!", Logger.Type.Info);
}

And the event functions:

private static void KeyEvent(object sender, KeyEventArgs eventArgs)
{
    Logger.Log(eventArgs.KeyCode.ToString());
}
private static void MouseEvent(object sender, MouseEventArgs eventArgs)
{
    Logger.Log(eventArgs.Button.ToString());
}

You can find the whole class (and the project) here.

The constructor is the only thing that gets executed in the program.

What I found regarding the lag is that the event function has to be fast. That cannot be the problem in my case because the Logger.Log() function is fast, and the lag also occurs when using Console.WriteLine().

As I said, the example program runs fine. I tried copying the example code, but that made no difference. The only real difference between my program and the example program is that the example uses .Net Core but I use .Net Framework (4.8). Could that be the reason? If it is the reason, is there any way to use the library with .Net Framework? I look forward to any help.


Solution

  • There are two issues:

    • You need a message pump in order to receive hook messages. For this you can use the following code, as shown in the example you link
    Application.Run(new ApplicationContext());
    
    • You now have two things you are trying to do on the same thread: pump the messages and wait for input. Instead, split them into different threads:
    private static void Main(string[] args)
    {
        Logger.Log("Program started. Welcome.", Logger.Type.Info);
        ////GameSense.Controller.Start();
        new Thread(() => Console.ReadLine()).Start();
                
        InputManager.Start();
        
        Application.Run(new ApplicationContext());
        InputManager.End();
        Application.Exit();  // needed to close down the message pump and end the other thread
    }