No se puede detectar el mouse global hacia abajo con MouseKeyHook

Dec 31 2020

He estado investigando durante las últimas horas para descubrir cómo detectar los clics izquierdo del mouse a nivel mundial (no enfocado) y me encontré con múltiples publicaciones que mencionan el uso de globalmousekeyhook que instalé a través de NuGet que he implementado como se ve a continuación:

using Gma.System.MouseKeyHook;
using System;

namespace mouse_hook_test
{
    class Program
    {
        static private IKeyboardMouseEvents m_GlobalHook;

        static void Main(string[] args)
        {
            Subscribe();

            Console.ReadKey();
        }

        static public void Subscribe()
        {
            m_GlobalHook = Hook.GlobalEvents();

            m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt;
        }

        static private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e)
        {
            Console.WriteLine("Mouse Click.");
        }
    }
}

Cuando lo ejecuto, mi mouse en pantalla de repente comienza a retrasarse hasta el punto en que no se puede usar (incluso luché para cerrar el símbolo del sistema) y también intenté hacer clic tanto a la izquierda como a la derecha, pero no se registra nada. ¿Estoy haciendo algo completamente estúpido? Siento que hay algo realmente obvio que me estoy perdiendo porque nadie más tiene este problema, o si hay otra solución, estaría encantado de intentarlo. Gracias.

Visual Studio 2019, Windows 10 Pro, Proyecto: .NET Framework 4.7.2, Aplicación de consola, se ejecutó con el modo de depuración

Respuestas

EpicSpeedy Jan 03 2021 at 08:41

De hecho, estaba jugando como de costumbre, buscando diferentes formas de hacerlo y luego me topé con la función de la API de Windows para obtener los estados de las claves (GetKeyStates) (incluido el mouse), así que importé la DLL de user32 y comencé un ciclo que verifica el botón izquierdo del mouse state ( 0x01) cada 50ms (encontró que es el mejor momento) y lo lanzó en un hilo para que no bloqueara el principal.

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace mouse_hook_test
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(detect);
            thread.Start();
        }

        // Import the DLL that contains the function and grab it.
        [DllImport("user32.dll")]
        public static extern short GetKeyState(int vKey);

        // A very simple implementation for tracking the state of the left mouse button.
        static void detect()
        {
            short oldState = GetKeyState(0x01);

            while (true)
            {
                short newState = GetKeyState(0x01);                

                if (oldState != newState)
                {
                    oldState = newState;

                    if (newState < 0)
                    {
                        onMouseClick();
                    }
                }

                Thread.Sleep(50);
            }
        }

        static void onMouseClick()
        {
            Console.WriteLine("Clicked!");
        }
    }
}

Probablemente haya una mejor solución para esto (que no pude encontrar) y por qué estoy usando esto. Originalmente basé esto en una respuesta a mi pregunta exacta, pero en cambio estaba escrito en Python, así que lo convertí a C #. Me estaba cansando de ver que la única respuesta a mi pregunta era 'usar alguna biblioteca de terceros' que no funciona correctamente para mí por cualquier motivo y también ha reducido el uso de memoria de 30mb a 7mb :).

También lo he probado en Windows 7 y funciona de maravilla.