Como você sabe: C# é uma linguagem complementar à plataforma .NET Framework, e não é possível implementar ganchos globais com suas próprias bibliotecas e provisões de compilador. Mas, na prática, chamadas para código não gerenciado são verdadeiras em C#, usando a propriedade DllImport para referenciar métodos na biblioteca de código não gerenciada. Funções hook existem em user32.dll, e o protótipo da função é o seguinte:
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId);
Ele pode ser usado para registrar um tipo específico de método de processamento de interceptação de mensagens com o sistema operacional (Windows), por exemplo, podemos registrar um gancho para bloquear mensagens globais de teclado, de modo que todos os eventos de pressão e levantamento do teclado possam ser percebidos e processados por nós (não está descartado que exista um gancho front-end para deixar a mensagem).
Podemos referenciar essa função em C# declarando-a assim:
[DllImport("user32.dll")] public static extern int SetWindowsHookEx( Tipo de Hook idHook, HookProc lpfn, IntPtr hInstance, int threadId );
Vale mencionar que o HookType e o HookProc acima são meus tipos personalizados, o que não é importante (porque o programa passa um endereço de memória ao rodar), mas deve atender a certas especificações.
Os parâmetros da função de cima para baixo são:
tipo idHook, que é representado aqui por um enum moldado Função de retorno de chamada LPFN quando os ganchos entram em ação hInstance módulo handle da instância de aplicação (geralmente o handle do módulo da instância de aplicação onde sua função de callback de hook está localizada) threadIdO identificador da thread associada à sub-rotina de hook instalada
Existem vários tipos de ganchos:
Geralmente usamos 13 para bloquear mensagens de teclado e 14 para bloquear mensagens de mouse.
A declaração da função de callback Precisamos usar delegados em C#, e a declaração é a seguinte: delegado público int HookProc(int nCode, int wParam, IntPtr lParam);
O parâmetro top-down significa que o parâmetro repassado pela cadeia de gancho nCode, 0 significa que essa mensagem (pelo gancho anterior) é descartada, e non-0 significa que essa mensagem continua válida
Parâmetros da mensagem wParam
Parâmetro de mensagem lParam
Vale mencionar que wParam e iParam são tipos diferentes de tipos diferentes de mensagens, mas os tipos de wParam podem ser representados aproximadamente pela seguinte enumeração:
O lParam geralmente é encapsulado como uma estrutura, que varia dependendo do tipo de mensagem; as duas estruturas seguintes são a estrutura do lParam para mensagens de mouse e teclado:
Quando entendemos as informações acima, temos uma compreensão básica da implementação em C# das funções hook, e então prestamos atenção a algumas perguntas:
1. Hooks consomem muitos recursos e devem ser cancelados a tempo quando não estiverem em uso, o que requer o uso da função UnhookWindowsHookEx
2. Por cortesia, o gancho deve retornar o resultado de processamento do próximo gancho, não o resultado do processamento do gancho atual sozinho (use o CallNextHookEx para chamar o próximo gancho, já que o gancho é primeiro e depois entra em vigor, então deve ser feito para garantir a entrega normal da cadeia de ganchos).
3. A hInstância no parâmetro da função hook é apenas onde está a função de callback do hook atual, e o endereço correto deve ser fornecido
4. Como o delegado é usado, deve-se garantir que o endereço de memória do delegado (referência ao método) não seja inutilizado, caso contrário haverá uma exceção quando o gancho for executado
Você pode baixar o programa de exemplo que escrevi, mas meu programa precisa dos seguintes pontos principais:
1. Bloqueei a implementação de hooks e só abri a interceptação de mensagens e processamento de teclado e mouse (o método de uso é o mesmo dos eventos de mouse e teclado do WinForm do C#), e você pode abrir outros
2. Projetei o gancho para ficar no modo singleton, você pode cancelar
3. Devido a certa intrusão no sistema operacional, o software antivírus pode ser reportado como arriscado
4. O código está mal escrito, apenas se vire......
Por fim, a diferença entre tecnologia de programação e linguagem é que seus compiladores e usuários são diferentes, pessoas que usam C não podem ser consideradas superiores às que usam Java, e a tecnologia não é necessariamente refletida em ponteiros, matrizes, estruturas de dados, desde que pessoas que entendam princípios de computador, de compilação, de sistema operacional, etc. Claro, é bom que cada um tenha sua própria linguagem favorita e seus métodos habituais de programação.
|