Como sabéis: C# es un lenguaje complementario de la plataforma .NET Framework, y no es posible implementar ganchos globales con sus propias librerías y provisiones de compilador. Pero en la práctica, las llamadas a código no gestionado se cumplen en C#, usando la propiedad DllImport para referenciar métodos en la biblioteca de código no gestionado. Las funciones hook existen en user32.dll, y el prototipo de función es el siguiente:
HHOOK WINAPI SetWindowsHookEx(
__in en idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId);
Puede usarse para registrar un tipo específico de método de procesamiento de interceptación de mensajes con el sistema operativo (Windows), por ejemplo, podemos registrar un gancho para bloquear mensajes globales de teclado, de modo que todos los eventos de pulsación y levantamiento del teclado puedan ser percibidos y procesados por nosotros (no se descarta que exista un gancho frontal para soltar el mensaje).
Podemos referenciar esta función en C# declarándola así:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( Tipo de anzuelo idHook, HookProc lpfn, IntPtr hInstance, int threadId );
Cabe mencionar que el HookType y el HookProc anteriores son mis tipos personalizados, lo cual no es importante (porque el programa pasa una dirección de memoria al ejecutarse), pero debe cumplir ciertas especificaciones.
Los parámetros de la función de arriba a abajo son:
tipo idHook, que aquí se representa mediante un enum con forma Función de callback LPFN cuando entran en juego los ganchos Handle de módulo de instancia de la instancia de aplicación (normalmente el handle de módulo de la instancia de aplicación donde se encuentra la función de callback de hook) threadIdEl identificador del hilo asociado con la subrutina de gancho instalada
Existen varios tipos de ganchos:
Normalmente usamos 13 para bloquear mensajes de teclado y 14 para bloquear mensajes de ratón.
La declaración de la función de callback Necesitamos usar delegados en C#, y la declaración es la siguiente: delegado público int HookProc(int nCode, int wParam, IntPtr lParam);
El parámetro de arriba hacia abajo significa que el parámetro devuelto por la cadena de gancho nCode, 0 significa que este mensaje (por el gancho anterior) se descarta, y no-0 significa que este mensaje sigue siendo válido
Parámetros del mensaje wParam
Parámetro de mensaje lParam
Cabe mencionar que wParam e iParam son diferentes tipos de distintos tipos de mensajes, pero los tipos de wParam pueden representarse aproximadamente mediante la siguiente enumeración:
Generalmente se encapsula el Param como una estructura, que varía según el tipo de mensaje; las siguientes dos estructuras son la estructura del lParam de mensajes de ratón y teclado:
Cuando entendemos la información anterior, tenemos una comprensión básica de la implementación en C# de funciones hook, y luego prestamos atención a algunas preguntas:
1. Los hooks consumen muchos recursos y deben cancelarse a tiempo cuando no se usen, lo que requiere el uso de la función UnhookWindowsHookEx
2. Por cortesía, el gancho debe devolver el resultado de procesamiento del siguiente anzuelo, no solo el resultado del gancho actual (usa CallNextHookEx para llamar al siguiente anzuelo, ya que el gancho se activa primero y luego entra en vigor, así que debe hacerse para asegurar la entrega normal de la cadena de gancho).
3. La hInstance en el parámetro de la función hook es solo donde está la función de callback del hook actual, y debe darse la dirección correcta
4. Como se usa el delegado, debe asegurarse de que la dirección de memoria del delegado (referencia al método) no se desaproveche, de lo contrario habrá una excepción cuando se ejecute el hook
Puedes descargar el programa de ejemplo que escribí, pero mi programa necesita los siguientes puntos principales:
1. Bloqueé la implementación de ganchos y solo abrí la interceptación de mensajes y el procesamiento de teclado y ratón (el método de uso es el mismo que los eventos de ratón y teclado de WinForm en C#), y puedes abrir otros
2. Diseñé el gancho para que estuviera en modo singleton, puedes cancelarlo
3. Debido a cierta intrusión en el sistema operativo, el software antivirus puede considerarse riesgoso
4. El código está mal escrito, así que mejor apañárselo......
Por último, la diferencia entre tecnología de programación y lenguaje es que sus compiladores y usuarios son diferentes, no se puede decir que las personas que usan C sean superiores a las que usan Java, y la tecnología no se refleja necesariamente en punteros, matrices, estructuras de datos, siempre que las personas que entiendan los principios de ordenador, de compilación, de sistemas operativos, etc. Por supuesto, es bueno que cada uno tenga su propio lenguaje favorito y métodos habituales de programación.
|