Global keyboard hook mit WH_KEYBOARD_LL und keybd_event (windows)
Bin ich zu schreiben versucht, von einer einfachen globalen Tastatur-hook-Programm umleiten Sie einige Tasten. Zum Beispiel, wenn das Programm ausgeführt wird, drücke ich " a " auf der Tastatur, das Programm zu deaktivieren und zu simulieren, die ein 'b' klicken. Ich brauche nicht eine grafische Benutzeroberfläche, die nur eine Konsole ist genug (damit es läuft)
Mein plan ist die Verwendung von globalen hook zu fangen, den key eingegeben, und verwenden Sie dann keybd_event zu simulieren, die Tastatur. Aber ich habe einige Probleme.
Das erste problem ist, dass das Programm ordnungsgemäß block " A "aber wenn ich drücke" A " auf der Tastatur einmal, das printf () in der callback-Funktion wird zweimal ausgeführt, sowie die keybd_event. Also, wenn ich öffne eine txt-Datei, klicken Sie auf i 'A' mal, es gibt zwei " B 's-Eingang. warum ist das so?
Die zweite Frage ist, warum der Haken mit der WH_KEYBOARD_LL kann die Arbeit an anderen Verfahren ohne dll? Ich dachte, wir hatten eine dll verwenden, um einen globalen hook, bis ich schrieb dieses Beispiel...
#include "stdafx.h"
#include <Windows.h>
#define _WIN32_WINNT 0x050
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
BOOL fEatKeystroke = FALSE;
if (nCode == HC_ACTION)
{
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (fEatKeystroke = (p->vkCode == 0x41)) { //redirect a to b
printf("Hello a\n");
keybd_event('B', 0, 0, 0);
keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
break;
}
break;
}
}
return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}
int main()
{
//Install the low-level keyboard & mouse hooks
HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
//Keep this app running until we're told to stop
MSG msg;
while (!GetMessage(&msg, NULL, NULL, NULL)) { //this while loop keeps the hook
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hhkLowLevelKybd);
return(0);
}
Vielen Dank!
nach msdn.microsoft.com/en-us/library/windows/desktop/... - "...möglicherweise ein Wert ungleich null, um zu verhindern, dass das system von der Weitergabe der Nachricht an den rest der hook-Kette, oder in der Ziel-Fenster-Prozedur". Für mich verhindert, dass das system von der Weitergabe der Nachricht an den Ziel-Fenster-Prozedur sieht genau, wie blockieren.
Für diejenigen, die versuchen, diese zu arbeiten, aber erhält ERROR_HOOK_NEEDS_HMOD (1428): laut SetWindowsHookEx doc, "ein Fehler kann auftreten, wenn der hMod-parameter NULL ist und die dwThreadId-parameter ist null". Daher müssen Sie angeben
hMod
, aber in diesem Fall können Sie alle rechtlichen Wert, da keine DLL wird injected sowieso für low-level-hooks. Sie können zum Beispiel GetModuleHandle("kernel32.dll")
.
InformationsquelleAutor user1722361 | 2014-04-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste ist einfach. Sie bekommen einen Schlüssel für unten und eine weitere für die Schlüssel. 🙂
Als für die, warum es funktioniert, ohne eine DLL - das ist, weil es einen globalen hook. Im Gegensatz zu thread-spezifisch durchgeführt, ist in Ihrem eigenen Prozess, nicht der Prozess, mit dem Tastatur-Ereignis passiert ist. Es geschieht über das senden von Nachrichten auf den thread, was hat die den hook installiert - das ist genau das, warum müssen Sie die message-loop hier. Ohne Ihre Haken nicht ran, da gab es niemanden, der für eingehende Nachrichten.
Die DLL-Datei ist erforderlich für thread-spezifische Haken, weil Sie genannt sind in den Kontext eines anderen Prozesses. Damit dies funktioniert, ist Ihr DLL-Injektion in diesem Prozess. Es ist nur hier nicht der Fall.
Das ist alles ganz falsch. Alle global-Haken müssen in einer DLL sein, es sei denn, es ist ein low-level-hook. In der Dokumentation fehlt. Die Sprache ist C++, aber C# verwenden können low-level-hooks, weil Sie nicht verlangen, eine DLL.
InformationsquelleAutor Ivan Danilov
Ihre callback-Funktion ausführen zweimal wegen
WM_KEYDOWN
undWM_KEYUP
.Wenn Sie unten eine Taste auf Ihrer Tastatur, windows ruft die callback-Funktion mit
WM_KEYDOWN
Nachricht und wenn Sie die Taste loslassen, windows ruft die callback-Funktion mitWM_KEYUP
Nachricht. Das ist, warum Sie Ihre callback-Funktion ausführen zweimal.Sollten Sie Ihre switch-Anweisung:
Über Ihre zweite Frage, ich denke Sie haben bereits von @Ivan Danilov Antwort.
InformationsquelleAutor Forhad Reza
InformationsquelleAutor Hung Minh Tran