Impossible de détecter la souris globale avec MouseKeyHook

Dec 31 2020

J'ai fait des recherches ces dernières heures pour comprendre comment détecter les clics gauche de la souris dans le monde (non ciblé) et je suis tombé sur plusieurs articles mentionnant l'utilisation de globalmousekeyhook que j'ai installé via NuGet que j'ai implémenté comme indiqué ci-dessous:

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.");
        }
    }
}

Lorsque je l'exécute, ma souris à l'écran commence soudainement à être en retard au point où elle est inutilisable (j'ai même eu du mal à fermer l'invite de commande) et j'ai également essayé de cliquer à gauche et à droite, mais rien n'est enregistré. Est-ce que je fais quelque chose de complètement stupide? Je pense qu'il me manque quelque chose de vraiment évident parce que personne d'autre n'a ce problème, ou s'il y a une autre solution, je serais heureux de l'essayer. Merci.

Visual Studio 2019, Windows 10 Professionnel, Projet: .NET Framework 4.7.2, Application console, exécuté avec le mode débogage

Réponses

EpicSpeedy Jan 03 2021 at 08:41

Je jouais en fait comme d'habitude, cherchant différentes façons de le faire, puis je suis tombé sur la fonction API Windows pour obtenir les états des touches (GetKeyStates) (y compris la souris), alors j'ai importé la DLL user32 et commencé une boucle qui vérifie l'état du bouton gauche de la souris ( 0x01) toutes les 50 ms (trouvé que c'était le meilleur moment) et l'a jeté dans un thread pour ne pas bloquer le 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!");
        }
    }
}

Il existe probablement une meilleure solution pour cela (que je n'ai pas pu trouver) et pourquoi j'utilise cela. Je me suis basé à l'origine sur une réponse à ma question exacte, mais à la place, elle a été écrite en Python, je l'ai donc convertie en C #. J'en avais marre de voir que la seule réponse à ma question était `` d'utiliser une bibliothèque tierce '' qui ne fonctionne pas correctement pour moi pour une raison quelconque et qui a également réduit l'utilisation de la mémoire de 30 Mo à 7 Mo :).

Je l'ai également testé sur Windows 7 et cela fonctionne à merveille.