Ahogy tudod: a C# a .NET Framework platform társnyelve, és nem lehetséges globális hookokat saját könyvtárakkal, fordítórendszerekkel valósítani meg. A gyakorlatban azonban a menedzselt nélküli kód hívásai C#-ban is igazak maradnak, a DllImport tulajdonságot használva a menedzselt kódkönyvtár metódusainak hivatkozására. A horogfüggvények léteznek user32.dll-ben, és a függvény prototípusa a következő:
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId);
Használható egy speciális típusú üzenetlehallgatási feldolgozási módszer regisztrálására az operációs rendszeren (Windows), például regisztrálhatunk egy horgot, amely blokkolja a globális billentyűzet üzeneteket, így minden billentyűzetes nyomás és emelés eseményt észlelhetünk és feldolgozhatunk (nem zárjuk ki, hogy van front-end hook az üzenet eldobásához).
Ezt a függvényt C#-ban így állíthatjuk meg:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( HookType idHook, HookProc lpfn, IntPtr hInstance, int threadId );
Érdemes megemlíteni, hogy a fent említett HookType és HookProc az egyedi típusaim, ami nem fontos (mert a program futás közben memóriacímet ad át), de bizonyos specifikációknak kell megfelelnie.
A függvény paraméterei felülről lefelé a következők:
idHook típus, amelyet itt egy formált enum képvisel LPFN visszahívási funkció, amikor a horgok lépnek fel az alkalmazás példány hInstance modul handle (általában annak az alkalmazáspéldánynak a modul fogantyű, ahol a hook callback függvény található) threadIdAz a szál azonosítója, amely a telepített hook alprogramhoz kapcsolódik
Többféle kampó létezik:
Általában 13-at használunk a billentyűzetes üzenetek blokkolására, a 14-et az egérüzenetek blokkolására.
A visszahívási függvény kijelentése C#-ban kell küldötteket használnunk, és a deklaráció a következő: public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
A felülről lefelé mutató paraméter azt jelenti, hogy az nCode hook láncon keresztül visszaküldött paraméter, 0 azt jelenti, hogy ez az üzenet (az előző üzenet hookja által) eldobódik, a nem 0 pedig azt jelenti, hogy az üzenet továbbra is érvényes
wParam üzenetparaméterek
lParam üzenetparaméter
Érdemes megemlíteni, hogy a wParam és az lParam különböző típusú üzenettípusok, de a wParam típusai nagyjából a következő felsorolással reprezentálhatók:
Az lParam általában egy szerkezetként van bezárva, amely az üzenet típusától függően változik; a következő két struktúra az egér- és billentyűzetüzenetek lParam szerkezete:
Ha megértjük a fenti információkat, alapvetően megértjük a hook függvények C# megvalósítását, majd figyelünk néhány kérdésre:
1. A hookok rengeteg erőforrást foglalnak, és időben törölni kell, ha nem használják, ami az UnhookWindowsHookEx funkciót igényli
2. Udvariasságból a hooknak a következő hook feldolgozási eredményét kell visszaadnia, nem csak a jelenlegi horog feldolgozási eredményét (használd a CallNextHookEx-et a következő hook meghívására, mivel a horog van először beállítva, majd lép életbe, így ezt a hooklánc normál kézbesítése érdekében kell megtenni).
3. A hInstance a hook függvény paraméterben csak ott van, ahol a jelenlegi hook visszahívási függvénye van, és a helyes címet kell megadni
4. Mivel a delegált van használatban, biztosítani kell, hogy a delegált memóriacíme (a metódusra való hivatkozás) ne legyen hulladék, különben kivétel lesz a hook végrehajtása esetén
Letöltheted a mintaprogramot, amit írtam, de az én programomnak a következő fő pontokra van szüksége:
1. Blokkoltam a hookok megvalósítását, és csak a billentyűzet és egér üzenetlehallgatását és feldolgozását nyitottam meg (a használati mód ugyanaz, mint a C# WinForm egér- és billentyűzet eseményei), és te meg tudod nyitni a többi esetet
2. Úgy terveztem a horgot, hogy egy-egy módban legyen, lemondhatod
3. Az operációs rendszerbe való bizonyos behatolás miatt az antivírus szoftvereket kockázatosnak jelenthetik
4. A kód rosszul van megírva, csak elég be vele......
Végül a programozási technológia és a nyelv közötti különbség az, hogy a fordítóik és a felhasználók különböznek, a C-t használók nem mondhatják, hogy magasabb szintűek a Java-t használóknál, és a technológia nem feltétlenül tükröződik mutatókban, mátrixokban, adatstruktúrákban, amíg azok értik a számítógép-alapokat, fordítási elveket, operációs rendszer elveket stb. Természetesen jó, hogy mindenkinek megvan a saját kedvenc nyelve és a szokásos programozási módszerei.
|