[C# 2008] Registrare comandi da tastiera

giovedì 11 settembre 2008 - 16.28

julius92 Profilo | Newbie

Ciao a tutti,
come posso fare per registrare tutti i tasti premuti anche quando la mia finestra ha perso il focus?
Grazie in anticipo.

aiedail92 Profilo | Expert

Ciao

Quello che vuoi fare è un keylogger, uno strumento da usare solo con buoni propositi...

Ti dò un avviamento sulla strada da seguire: quello che bisogna fare è installare un Hook nel sistema, questo usando una chiamata all'API SetWindowsHookEx:

[DllImport("user32.dll")] static extern IntPtr SetWindowsHookEx( int idHook, //Il tipo di hook da installare KeybordProcDelegate lpfn, //La funzione chiamata dall'hook IntPtr hMod, //L'handle del modulo dove risiede la lpfn uint dwThreadId); //Il thread id a cui è associata lpfn

La firma del delegato per l'hook da tastiera è questa:

delegate IntPtr KeybordProcDelegate(int code, IntPtr wParam, IntPtr lParam);

Devi indicare all'API che l'hook deve monitorare la tastiera, questo sfruttando opportunamente il primo parametro dell'API:

private const int WH_KEYBOARD = 2; private const int WH_KEYBOARD_LL = 13; //Eventi di tastiera a basso livello

Il penultimo parametro deve essere ottenuto tramite l'API GetModuleHandle(null) (ottiene l'handle del codulo corrente)

[DllImport("kernel32.dll")] static extern IntPtr GetModuleHandle(string lpModuleName);

E l'ultimo parametro deve essere 0 per impostare l'hook su tutti i thread.

Quando ricevi un messaggio dalla procedura di Hook, prima di uscire devi chiamare l'API CallNextHookEx:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

E prima di terminare l'applicazione devi chiamare l'API UnHookWindowsHookEx:

[DllImport("user32.dll")] private static extern bool UnhookWindowsHookEx(IntPtr hhk);

Questa è la documantazione su MSDN: http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx

Luca

julius92 Profilo | Newbie

Ho provato, ma esegue due volte il delegato.

aiedail92 Profilo | Expert

Dunque, forse è per il fatto che l'evento viene generato sia quando il tasto viene premuto che quando viene rilasciato. Consulta bene la documantazione (http://msdn.microsoft.com/en-us/library/ms644985(VS.85).aspx) per capire quale tipo di evento è stato scatenato.

Poi volevo aggiungere (anche se forse non sono la persona più indicata a farlo) che l'attività svolta da un KeyLogger viola la privacy dell'utente (qualora non venga informato), pertanto può costituire un'attività illegale. Pertanto non diffondere un software potenzialmente illecito/dannoso.

Luca

julius92 Profilo | Newbie

Ok.
Come posso conoscere quale tasto è stato premuto?

Il mio programma comunque usa lecitamente tale funzione, la usa per un comando speciale da tastiera che do' da un'altro programma (una sorta di hotkey).

Ciao

aiedail92 Profilo | Expert

Dipende da quale hook hai installato: un WH_KEYBOARD o un WH_KEYBOARD_LL?

Luca

julius92 Profilo | Newbie

Ho usato un WH_KEYBOARD_LL.

aiedail92 Profilo | Expert

In tal caso il parametro lParam contiene un puntatore a una struttura che in C# si wrappa in questo modo:

[StructLayout(LayoutKind.Sequential)] struct KBDLLHOOKSTRUCT { uint vkCode; uint scanCode; uint flags; uint time; ulong dwExtraInfo; }

Per cui puoi decidere di convertire il puntatore su questo tipo di struttura, usando

KBDLLHOOKSTRUCT lP = Marshal.PtrToStruct(lParam, typeof(KBDLLHOOKSTRUCT));

oppure leggere solo il primo parametro (che contiene il virtual key code del tasto) usando il metodo

uint vkey = (uint)Marshal.ReadInt32(lParam);

Luca

julius92 Profilo | Newbie

Grazie di tutto.
Ciao.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5