După cum știți: C# este un limbaj companion pentru platforma .NET Framework și nu este posibil să implementezi hook-uri globale cu propriile biblioteci și prevederi de compilare. Dar, în practică, apelurile către cod neadministrat sunt valabile în C#, folosind proprietatea DllImport pentru a face referire la metode din biblioteca de cod neadministrată. Funcțiile hook există în user32.dll, iar prototipul funcției este următorul:
HHOOK WINAPI SetWindowsHookEx(
__in în idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId);
Poate fi folosit pentru a înregistra un anumit tip de metodă de procesare a interceptării mesajelor în sistemul de operare (Windows), de exemplu, putem înregistra un hook pentru a bloca mesajele globale de la tastatură, astfel încât toate evenimentele de apăsare și ridicare a tastaturii să poată fi percepute și procesate de noi (nu se exclude existența unui hook front-end pentru a elimina mesajul).
Putem face referire la această funcție în C# declarând-o astfel:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( HookType idHook, HookProc lpfn, IntPtr hInstant, int threadId );
Merită menționat că HookType și HookProc de mai sus sunt tipurile mele personalizate, ceea ce nu este important (pentru că programul transmite o adresă de memorie când rulează), dar trebuie să respecte anumite specificații.
Parametrii funcției de sus în jos sunt:
tipul idHook, reprezentat aici printr-un enum modelat Funcția de apel înapoi LPFN când intră în joc hook-urile hInstance module handle al instanței aplicației (de obicei handle-ul modulului al instanței aplicației unde se află funcția de apel hook) threadIdIdentificatorul firului asociat cu subrutina hook instalată
Există mai multe tipuri de cârlige:
De obicei folosim 13 pentru a bloca mesajele de la tastatură și 14 pentru a bloca mesajele mouse-ului.
Declarația funcției de callback Trebuie să folosim delegați în C#, iar declarația este următoarea: delegat public int HookProc(int nCode, int wParam, IntPtr lParam);
Parametrul top-down înseamnă că parametrul transmis înapoi de lanțul de hook nCode, 0 înseamnă că acest mesaj (de către hook-ul anterior) este eliminat, iar non-0 înseamnă că acest mesaj continuă să fie valid
Parametrii mesajului wParam
Parametrul mesajului lParam
Merită menționat că wParam și lParam sunt tipuri diferite de tipuri diferite de mesaje, dar tipurile de wParam pot fi reprezentate aproximativ prin următoarea enumerare:
LParam este în general încapsulată ca o structură, care variază în funcție de tipul mesajului; următoarele două structuri sunt structura lParam a mesajelor mouse și tastatură:
Când înțelegem informațiile de mai sus, avem o înțelegere de bază a implementării în C# a funcțiilor hook și apoi acordăm atenție câtorva întrebări:
1. Hook-urile consumă multe resurse și ar trebui anulate la timp când nu sunt folosite, ceea ce necesită utilizarea funcției UnhookWindowsHookEx
2. Din curtoazie, cârligul ar trebui să returneze rezultatul procesării următorului cârlig, nu rezultatul procesării doar al cârligului curent (folosiți CallNextHookEx pentru a chema următorul cârlig, deoarece cârligul este setat primul și apoi intră în vigoare, deci acest lucru trebuie făcut pentru a asigura livrarea normală a lanțului cârligului).
3. Instanța hInstance din parametrul funcției hook este doar acolo unde se află funcția de callback a hook-ului curent, iar adresa corectă trebuie să fie dată
4. Deoarece delegatul este folosit, trebuie asigurat că adresa de memorie a delegatului (referință la metodă) nu va fi defecționată, altfel va exista o excepție când hook-ul este executat
Poți descărca programul exemplu pe care l-am scris, dar programul meu are nevoie de următoarele puncte principale:
1. Am blocat implementarea hook-urilor și am deschis doar interceptarea mesajelor și procesarea tastaturii și mouse-ului (metoda de utilizare este aceeași ca la evenimentele de mouse și tastatură WinForm din C#), iar altele pot deschide altele
2. Am proiectat cârligul să fie în modul singleton, poți să-l anulezi
3. Din cauza anumitor intruziuni în sistemul de operare, software-ul antivirus poate fi raportat ca fiind riscant
4. Codul este prost scris, doar te descurci cu el......
În cele din urmă, diferența dintre tehnologia programării și limbaj este că compilatoarele și utilizatorii lor sunt diferiți, oamenii care folosesc C nu pot fi considerați superiori celor care folosesc Java, iar tehnologia nu se reflectă neapărat în pointere, matrici, structuri de date, atâta timp cât oamenii care înțeleg principiile calculatoarelor, principiile de compilare, principiile sistemului de operare etc. Desigur, este bine că fiecare are limbajul preferat și metodele obișnuite de programare.
|