SwordMaster Geschrieben 28. März 2014 Geschrieben 28. März 2014 (bearbeitet) Hallo Zusammen, Ich habe ein Programm für das ich einen KeyHook benötige. Das Problem: Der KeyHook funktioniert auch. Jedoch nach einer kurzen zeit (manchmal 5 min, 10 min, manchmal länger... ) wird der hook einfach nicht mehr aufgerufen. Ich bekomme keinen Fehler und keine Exception.... :-/ Hier mein Coding... Ich hoffe ihr könntet mir einen Tip geben. Im INet konnte ich auch nichts finden. Wobei ich mich auch mit dem Suchen schwer tue, ich habe keine Fehlermeldung, Absturz, Exception oder ähnliches. Er funktioniert ja auch. jedoch nicht sehr lange :-( public struct KBDLLHOOKSTRUCT { public int flags; public int vkCode; } public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref ForeignKeyHook.KBDLLHOOKSTRUCT lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx( int hHook, int nCode, int wParam, ref ForeignLibraryNET.ForeignKeyHook.KBDLLHOOKSTRUCT lParam); private int LowLevelKeyboardProc(int nCode, int wParam, ref ForeignLibraryNET.ForeignKeyHook.KBDLLHOOKSTRUCT lParam) { switch (wParam) { case 260: //WM_SYSKEYDOWN = 0x0104 PostMessage(m_window, 12346, (IntPtr)lParam.vkCode, new IntPtr()); break; } return CallNextHookEx(0, nCode, wParam, ref lParam); } private void Form1_Shown(object sender, EventArgs e) { ForeignLibraryNET.ForeignKeyHook.LowLevelKeyboardProcDelegate del = new ForeignLibraryNET.ForeignKeyHook.LowLevelKeyboardProcDelegate(LowLevelKeyboardProc); ForeignLibraryNET.ForeignKeyHook hook = new ForeignLibraryNET.ForeignKeyHook(); hook.KeyboardHook(del) } Viele Grüße & Danke für alle Tipps. Stefan P.S. Ich verwende Visual C# Express 2008 mit .NET 3.5 Bearbeitet 28. März 2014 von SwordMaster Zitieren
Klotzkopp Geschrieben 28. März 2014 Geschrieben 28. März 2014 Vielleicht räumt der GC dein ForeignKeyHook-Objekt weg. Ist ja nur eine lokale Variable in Form1_Shown. Zitieren
SwordMaster Geschrieben 28. März 2014 Autor Geschrieben 28. März 2014 Hallo Klotzkopp Danke für den Tipp. Hat leider nichts gebracht. Hätte jetzt die Delegate und die Hook als statisches Klassenattribut definiert. Trotzdem tritt das Problem weiterhin auf. Zur Info: Die ForeignKeyHook Klasse hab ich in eine Klassenbibliothek ausgelagert (dll). Beim Aufruf der Methode ForeignKeyHook wird der Hook über: intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, del, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0); gestartet. Kann der Fehler hier irgendwo liegen? Weiteres seltsames Verhalten. Wenn ich beim KEYDOWN ein MessageBox einbaue, bekomme ich ca. 10-15 Mal eine Messagebox wenn ich eine Taste drücke, danach wird der Hook nicht mehr aufgerufen. Bau ich jedoch einen counter ein, und lass die Messagebox erst ab dem 100-Hook-Aufruf kommen, dann funktioniert der hook 110-115 mal. Sehr Strange... Hast du noch einen Tipp? Kann man so sachen wie den CG überwachen? Prüfen wann er aufgerufen wurde, und was er verworfen hat? Viele Grüße Stefan Zitieren
SwordMaster Geschrieben 28. März 2014 Autor Geschrieben 28. März 2014 Hallo, Um Abhängigkeiten zu meiner DLL oder sowas zu vermeiden, habe ich das Coding mal in ein komplett neues Projekt ohne dll oder sonstigen Funktionen verschoben.... Der Code (bzw. das neue Projekt) ist nicht so lange, hat aber das gleiche Problem. (Nach z.b. 11 MessageBoxen ist schluß... außer ich bau entsprechende IF's ein, dass die MessageBox erst später kommt...) public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int CallNextHookEx( int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam); [DllImport("user32.dll", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi)] private static extern int SetWindowsHookEx( int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); IntPtr m_window; public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam); public struct KBDLLHOOKSTRUCT { public int flags; public int vkCode; } const int WH_KEYBOARD_LL = 13; private int intLLKey; LowLevelKeyboardProcDelegate del; Process process; ProcessModule module; IntPtr hModule; private int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam) { switch (wParam) { case 256: //WM_KEYDOWN = 0x0100 MessageBox.Show("abc"); break; } return 0; } private void Form1_Shown(object sender, EventArgs e) { m_window = FindWindow(null, "DevBox"); process = Process.GetCurrentProcess(); module = process.MainModule; hModule = GetModuleHandle(module.ModuleName); del = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc); intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, del, hModule, 0); } } Zitieren
Klotzkopp Geschrieben 28. März 2014 Geschrieben 28. März 2014 Das Anzeigen einer MessageBox ist eine ganz schlechte Idee. Während dein Hook läuft, ist die Anwendung, die das Tastaturereignis generiert hat, blockiert. Nach kurzer Zeit "entsperrt" Windows die Anwendung wieder, wenn dein Hook nicht fertig wird. Es gibt auch eine Registry-Einstellung, die bewirkt, dass Windows zu langsame Hooks eigenmächtig entfernt. Generell sollte dein Hook sehr schnell arbeiten (ggf. die Arbeit an einen anderen Thread übergeben). Keinesfalls sollte er blockieren, wie z.B. mit MessageBox. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.