Jak wiesz: C# jest językiem towarzyszącym platformie .NET Framework i nie jest możliwe zaimplementowanie globalnych hooków z własnymi bibliotekami i provisionami kompilatora. W praktyce jednak wywołania do kodu niezarządzanego są prawdziwe w C#, wykorzystując właściwość DllImport do odwoływania się do metod w bibliotece kodu niezarządzanego. Funkcje haczyka istnieją w user32.dll, a prototyp funkcji wygląda następująco:
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCJA hMod,
__in DWORD dwThreadId);
Może być używany do rejestracji określonego typu metody przetwarzania przechwytywania wiadomości w systemie operacyjnym (Windows), na przykład możemy zarejestrować hak blokujący globalne wiadomości klawiaturowe, dzięki czemu wszystkie zdarzenia naciskania i podnoszenia klawiatury mogą być przez nas postrzegane i przetwarzane (nie jest wykluczone, że istnieje front-end hook do upuszczenia wiadomości).
Możemy odwołać się do tej funkcji w C#, deklarując ją w następujący sposób:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( HookType idHook, HookProc lpfn, IntPtr hInstance, int threadId );
Warto wspomnieć, że HookType i HookProc powyżej to moje niestandardowe typy, co nie jest istotne (ponieważ program przekazuje adres pamięci podczas działania), ale musi spełniać określone wymagania.
Parametry funkcji od góry do dołu to:
idHook, który tutaj jest reprezentowany przez ukształtowany enum Funkcja odwołania LPFN, gdy pojawiają się haki uchwyt modułu hInstance instancji instancji (zazwyczaj uchwyt modułu instancji, w której znajduje się funkcja hook callback) threadIdIdentyfikator wątku powiązanego z zainstalowanym podprogramem hook
Istnieje kilka rodzajów haczyków:
Zazwyczaj używamy 13 do blokowania wiadomości klawiaturowych i 14 do blokowania wiadomości myszy.
Deklaracja funkcji callback Musimy użyć delegatów w C#, a deklaracja wygląda następująco: delegat publiczny int HookProc(int nCode, int wParam, IntPtr lParam);
Parametr z góry oznacza, że parametr przekazany z powrotem przez łańcuch haków nCode, 0 oznacza, że ta wiadomość (przez poprzedni hak wiadomości) zostaje odrzucona, a nie-0 oznacza, że ta wiadomość pozostaje ważna
parametry wiadomości wParam
parametr komunikatu lParam
Warto wspomnieć, że wParam i lParam to różne typy różnych typów wiadomości, ale typy wParam można w przybliżeniu przedstawić następującą enumeracją:
lParam jest zazwyczaj zamknięty jako struktura, która różni się w zależności od rodzaju wiadomości; dwie następujące struktury to struktura lParam dla wiadomości myszy i klawiatury:
Gdy zrozumiemy powyższe informacje, mamy podstawową wiedzę o implementacji funkcji hook w C#, a następnie zwracamy uwagę na kilka pytań:
1. Haki zajmują dużo zasobów i powinny być anulowane na czas, gdy nie są używane, co wymaga użycia funkcji UnhookWindowsHookEx
2. Z uprzejmości, hak powinien zwracać wynik przetwarzania następnego haka, a nie tylko wynik przetwarzania bieżącego haka (użyj CallNextHookEx, aby wywołać następny hak, ponieważ hak jest najpierw ustawiony i potem wchodzi w życie, więc powinno to być zrobione, aby zapewnić normalne dostarczenie łańcucha haków).
3. HInstance w parametrze funkcji hook występuje tylko tam, gdzie funkcja callback aktualnego hooka jest i należy podać poprawny adres
4. Ponieważ delegat jest używany, należy mieć pewność, że adres pamięci delegata (odniesienie do metody) nie zostanie zgarnegowany, w przeciwnym razie pojawi się wyjątek przy wykonaniu hooka
Możesz pobrać przykładowy program, który napisałem, ale mój program wymaga następujących głównych punktów:
1. Zablokowałem implementację haków i otworzyłem tylko przechwytywanie i przetwarzanie wiadomości klawiaturą i myszką (metoda użycia jest taka sama jak w przypadku zdarzeń myszy i klawiatury w WinForm w C#), a inne można otworzyć
2. Zaprojektowałem hook w trybie singleton, można go anulować
3. Z powodu pewnego ingerencja w system operacyjny, oprogramowanie antywirusowe może być zgłaszane jako ryzykowne
4. Kod jest źle napisany, wystarczy się nim zadowolić......
Wreszcie, różnica między technologią programistyczną a językiem polega na tym, że ich kompilatory i użytkownicy są różni, nie można powiedzieć, że osoby używające C są wyżej niż te korzystające z Javy, a technologia niekoniecznie odzwierciedla się w wskaźnikach, macierzach, strukturach danych, o ile rozumieją zasady komputera, zasady kompilacji, systemów operacyjnych itd. Oczywiście dobrze, że każdy ma swój ulubiony język i zwykłe metody programowania.
|