2017-05-05 4 views
3

Je veux utiliser mono pour écrire un simple outil CL qui enregistre chaque clic sur le système. Je comprends que je peux y accéder à partir de Windows Forms? Qui est comme le wrapper autour de l'API Windows interne?Écoutez le clic du système en utilisant Mono et C#?

Désolé je suis une vraie question stupide mais venant d'un arrière-plan JS où c'est juste AddEventListener c'est un peu confus, ou mal documenté. Merci

+0

sur .NET Framework, vous pouvez utiliser PInvoke pour y parvenir, en appelant l'API Win32 pertinente. Mono vous permet de faire exactement la même chose. À propos de l'API Win32 à appeler et de l'utilisation de PInvoke, utilisez Google. –

+0

Par intérêt, puisque vous êtes sur Windows, pourquoi utilisez-vous Mono plutôt que le framework .NET? –

Répondre

2

Qu'est-ce que vous cherchez est en user32.dll


liens dont voici quelques à son sujet:

http://pinvoke.net/default.aspx/user32.GetAsyncKeyState

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx

looking up that the user press a key or not?


Le premier lien contient des exemples d'utilisation de la DLL.

Vous pouvez faire plusieurs choses avec cette DLL. Par exemple, ce que vous êtes après est

[DllImport("User32.dll")] 
private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey); 
[DllImport("User32.dll")] 
private static extern short GetAsyncKeyState(System.Int32 vKey); 

Pour cela, vous aurez besoin de vérifier la clé chaque fois que vous voulez vérifier si la touche est enfoncée. Vous pouvez utiliser le virtual key code ou utiliser la classe Keys.


Si vous souhaitez également simuler des événements de souris, envoyez un clic gauche par exemple au système, le code suivant est ce que vous êtes après. (Plus d'info here)

[DllImport("user32.dll")] 
static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, int dwExtraInfo); 

Je l'ai fait une chose semblable il n'y a pas longtemps, mais je lui agrafait dans le clavier et non la souris. Le processus est similaire, mais il est beaucoup plus facile de se connecter à un programme spécifique. Le code est ci-dessous sur la façon dont j'ai résolu mon problème.

Dans le code suivant, j'ai créé un événement qui se déclenchait chaque fois qu'une touche était enfoncée et envoyait le code clé en tant qu'argument d'événement.

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace KeyHook { 
    public class KeyHook { 
     const int WH_KEYBOARD_LL = 13; 

     const int WM_KEYDOWN = 0x0100; 
     const int WM_KEYUP = 0x0101; 

     delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

     LowLevelKeyboardProc _proc { get; set; } 

     IntPtr _hookID { get; set; } 

     public delegate void KeyHandler(Keys k); 
     public event KeyHandler OnKeyDown; 
     public event KeyHandler OnKeyUp; 

     public KeyHook() { 
      Initialize(); 
      _hookID = SetHook(_proc); 
     } 

     void Initialize() { 
      this._proc = HookCallback; 
      this._hookID = IntPtr.Zero; 
      Application.ApplicationExit += Application_ApplicationExit; 
     } 

     void Application_ApplicationExit(object sender, EventArgs e) { 
      UnhookWindowsHookEx(_hookID); 
     } 

     IntPtr SetHook(LowLevelKeyboardProc proc) { 
      using (Process curProcess = Process.GetCurrentProcess()) { 
       using (ProcessModule curModule = curProcess.MainModule) { 
        return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle 

(curModule.ModuleName), 0); 
       } 
      } 
     } 

     IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { 
      if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { 
       if (this.OnKeyDown != null) { 
        this.OnKeyDown((Keys)Marshal.ReadInt32(lParam)); 
       } 
      } else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) { 
       if (this.OnKeyUp != null) { 
        this.OnKeyUp((Keys)Marshal.ReadInt32(lParam)); 
       } 
      } 
      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     } 

     #region dll Imports 
     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, 

uint dwThreadId); 


     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     static extern bool UnhookWindowsHookEx(IntPtr hhk); 


     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 


     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     static extern IntPtr GetModuleHandle(string lpModuleName); 
     #endregion 
    } 
}