Както знаете: C# е спомагателен език на платформата .NET Framework и не е възможно да се реализират глобални хукове със собствени библиотеки и компилационни provisions. Но на практика извикванията към неуправляван код са верни в C#, като се използва свойството DllImport за препращане към методи в библиотеката с неуправляван код. Кука функции съществуват в user32.dll, а прототипът на функцията е следният:
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId);
Може да се използва за регистрация на специфичен тип метод за обработка на прихващане на съобщения с операционната система (Windows), например, можем да регистрираме кука, която блокира глобални съобщения на клавиатурата, така че всички събития при натискане и повдигане на клавиатурата да бъдат възприемани и обработени от нас (не се изключва възможността да има преден хук, който да пуска съобщението).
Можем да реферираме тази функция в C#, като я декларираме по следния начин:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( HookType idHook, HookProc lpfn, IntPtr hInstance, int threadId );
Струва си да се спомене, че HookType и HookProc по-горе са моите персонализирани типове, което не е важно (защото програмата предава адрес на паметта при изпълнение), но трябва да отговаря на определени спецификации.
Параметрите на функцията отгоре надолу са:
тип idHook, който тук е представен чрез оформен enum функция LPFN за обратно повикване, когато се включат куки hInstance модулен дескриптор на инстанцията на приложението (обикновено дескрипторът на модула на приложението, където се намира функцията за hook back) threadIdИдентификаторът на нишката, свързана с инсталираната hook подпрограма
Съществуват няколко вида куки:
Обикновено използваме 13 за блокиране на съобщения от клавиатурата и 14 за блокиране на съобщения с мишка.
Декларацията на функцията за обратно извикване Трябва да използваме делегати в C#, а декларацията е следната: публичен делегат в HookProc(int nCode, int wParam, IntPtr lParam);
Параметърът отгоре надолу означава, че параметърът, прехвърлен обратно от веригата на nCode, 0 означава, че това съобщение (от предишната кука) е изхвърлено, а не-0 означава, че това съобщение продължава да е валидно
параметри на съобщението wParam
Параметър на съобщението lParam
Струва си да се спомене, че wParam и lParam са различни типове съобщения, но типовете wParam могат грубо да се представят чрез следното изброяване:
lParam обикновено се капсулира като структура, която варира в зависимост от типа съобщение; следните две структури са lParam структурата на съобщенията с мишка и клавиатура:
Когато разберем горната информация, имаме основно разбиране за реализацията на кука функции в C# и след това обръщаме внимание на няколко въпроса:
1. Куките заемат много ресурси и трябва да бъдат отменени навреме, когато не се използват, което изисква използването на функцията UnhookWindowsHookEx
2. От учтивост, куката трябва да върне резултата от обработката на следващия кука, а не само резултата от текущата кука (използвайте CallNextHookEx, за да извикате следващия кука, тъй като куката е зададена първа и след това влиза в сила, така че това трябва да се направи, за да се гарантира нормалното предаване на веригата).
3. hInstance в параметъра на функцията hook е само там, където е функцията за връщане на повикване на текущата кука, и трябва да бъде даден правилният адрес
4. Тъй като се използва делегатът, трябва да се гарантира, че адресът на паметта на делегата (препратка към метода) няма да бъде изхвърлен, в противен случай ще има изключение при изпълнение на куката
Можете да изтеглите примерната програма, която написах, но моята програма изисква следните основни точки:
1. Блокирах внедряването на hooks и отворих само прихващането и обработката на съобщения на клавиатура и мишка (методът на използване е същият като при събитията с мишка и клавиатура в C# в WinForm), а можете да отворите и други
2. Проектирах куката да е в singleton режим, можеш да го отмениш
3. Поради определено проникване в операционната система, антивирусният софтуер може да бъде докладван като рисков
4. Кодът е зле написан, просто се смири с него......
Накрая, разликата между програмната технология и езика е, че техните компилатори и потребители са различни, хората, които използват C, не могат да се кажат, че са по-висши от тези, които използват Java, а технологията не е непременно отразена в указатели, матрици, структури от данни, стига хората, които разбират компютърни принципи, принципи на компилация, принципи на операционната система и т.н. Разбира се, добре е, че всеки има свой любим език и обичайни методи на програмиране.
|