none
KeyBoardHook ohne Fenster RRS feed

  • Frage

  • Hallo

    Mit SetWindowsHookEx (WH_KEYBOARD, ...) und CallNextHookEx kann mann ja
    Tastaturcodes belauschen. Ich habe eine DLL, die das macht, aktuell starte ich die
    aus einer WinForms-Anwendung in C#.
    Der einzige Daseinszweck des WinForms-Formular bzw -Anwendung ist,
    eine MessageLoop zu liefern und einen Prozess, in den hinein der
    globale DLL-KeyBoardHook geladen werden kann.
    Das Fenster brauche ich nicht wirklich.

    Frage: Kann man den Hook auch fensterlos laden?
    Wenn ich es richtig sehe, konsumiert der nicht die an das Fenster
    gerichteteten WM_KEYDOWN-Nachrichten, sondern die system-weiten -
    funktioniert daher auch mit Hidden Fenster.
    Stichwort ist windowless messageloop.
    Lösung sollte optimalerweise auch in managed C++ umsetzbar sein.

     

    Gruß,
    Christoph

    Samstag, 28. August 2010 10:55

Antworten

  • Das Problem war, dass ich WH_KEYBOARD verwendet habe.
    Dann brauche ich eine Message-Loop und eine DLL und bekomme
    dennoch nicht wirklich alle KeyCodes, bzw das Caller Fenster
    muss fokusiert sein.

    Mit WH_KEYBOARD_LL funktioniert das alles wie gewünscht -
    was die Keys angeht. Fensterlos war wohl eine etwas unvorbelastete
    Idee.
    Was das als UI nicht benötigte Fenster angeht,
    mach ich's einfach hidden.

    Gruß,
    Christoph

    Dienstag, 31. August 2010 20:34

Alle Antworten

  • Du verstehst nicht ganz wie ein Hook funktioniert bzw. WH_KEYBOARD.
    WH_KEYBOARD liefert Dir alle Keyboardnachrichten für den Thread in den die DLL injiziert wurde. Wird der Hook systemweit verwendet, dann wird der Hook in jeden "möglichen" Prozess injiziert, der auch eine Messageloop hat. Andere Threads können sowieso keine Tastaturnachrichten bekommen, denn Focus setzt auch Fenster und Nachrichtenschleife voraus.

    Lies mal den Intro in der MSDN über Hooks.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Sonntag, 29. August 2010 12:33
    Moderator
  • Du verstehst nicht ganz wie ein Hook funktioniert bzw. WH_KEYBOARD.
    WH_KEYBOARD liefert Dir alle Keyboardnachrichten für den Thread in den die DLL injiziert wurde. Wird der Hook systemweit verwendet, dann wird der Hook in jeden "möglichen" Prozess injiziert, der auch eine Messageloop hat. Andere Threads können sowieso keine Tastaturnachrichten bekommen, denn Focus setzt auch Fenster und Nachrichtenschleife voraus.

    Lies mal den Intro in der MSDN über Hooks.



    Hallo Martin,

    danke für Deine Antwort.
    Also vom Konzept her habe ich es wie unter "Using Hooks" beschreiben gemacht:
    DLL exportiert eine Hook-Install-Funktion, die ruft SetWindowsHookEx mit
    WH_KEYBOARD auf.
    Anwendung holt DLL mit LoadLibray und startet den Hook indirekt über
    die Install-Funktion.

    Rein empirisch gesehen "arbeitet" die DLL wie gewünscht - auch wenn das
    "hookende Fenster" nicht im Fokus ist bzw. auch wenn es unsichtbar o.
    minimiert ist.
    D.h. die KeyBoardProc empfängt (fast) alle WM_KEYDOWN sprich jeden Tastaturansschlag.
    Über einen Callback gibt sie auch Infos an den Caller-Prozess
    zurück.

    Der Kern der Frage war jetzt:
    Wenn der Hook offensichtlich funktioniert und ich dazu eben "nur" einen Message-Loop brauche,
    aber kein sichtbares oder fokusiertes Fesnter, wie kann ich das Fenster so knapp wie möglich halten?
    In der MSDN ist die Rede von message-only Windows .
    Ich wollte dazu nachfragen  ob so ein Window noch in der Lage ist,
    einen System-Hook zu starten oder ob nicht.

    Gruß,
    Christoph

    Sonntag, 29. August 2010 15:00
  • D.h. die KeyBoardProc empfängt (fast) alle WM_KEYDOWN sprich jeden Tastaturansschlag.
    Über einen Callback gibt sie auch Infos an den Caller-Prozess
    zurück.

    Das dürfte nur sein, wenn Du einen systemweiten Hook gesetzt hast. Nicht wenn Du gezielt einen Thread angibst! Dann dürftest Du nur die Nachrichten erhalten, die auch die Fenster dieses Threads betreffen.
    Wenn ein Thread verwendet wird und dazu der eigene, benötigt man auch keine DLL!

    Wenn der Hook offensichtlich funktioniert und ich dazu eben "nur" einen Message-Loop brauche,
    aber kein sichtbares oder fokusiertes Fesnter, wie kann ich das Fenster so knapp wie möglich halten?
    In der MSDN ist die Rede von message-only Windows<http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only>  .
    Ich wollte dazu nachfragen  ob so ein Window noch in der Lage ist,
    einen System-Hook zu starten oder ob nicht.

    Ich verstehe Deine Frage nicht. Um einen Hook zu erzeugen benötigst Du selbst kein Fenster (d.h. der Prozess der den Hook erzeugt). Ein Tastatur Hook macht aber selbst natürlich dann Sinn, wenn der Thread auf den man den Hook ansetzt ein Fenster hat, das sichtbar werden kann und auch den Fokus erhalten kann.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Sonntag, 29. August 2010 15:49
    Moderator
  • Hallo Martin

    also ich beschreib einfach mal mein Ziel:
    Ich möchte eine x-64-Ersatz für "WinKey" schreiben.
    Winkey ist ein Tool, um Hotkeys mit der Windows-Taste zu definieren.
    Auf meine Win 7 x64 tut Winkey nicht mehr..

    Meine Idee war schlicht:
    Belausche alle Tastencodes, prüfe, ob ein Winkey drin ist,
    wenn ja matche es gegen eine Liste der benutzerdinierten
    Key-Kombinationen. Bei Match: starte das Programm.

    Zum Belauschen der Keycodes, dachte ich, dass ein system-globaler Keyboard-
    Hook die richtige Idee wäre.
    Ist das insoweit nachvollziehbar? Oder gibt es bessere ALternativen?
    Da ich in dem Szenrio kein Fenster brauche - um irgendetwas darzustellen
    oder für User-Interaktion - wollte ich halt nur die minimale
    Variante eines Fensters erzeugen, damit der Hook halt klappt.

    Der Hook bekommt übrigens keine ThreadID überreicht, bzw null,
    sollte also system-global sein.

    Brauch ich für diese Szenario überhaupt ein Fenster und nur einen
    Prozess, dre die DLL am Leben hält?

    Gruß,
    Christoph

     

     

    Dienstag, 31. August 2010 14:13
  • Das Problem war, dass ich WH_KEYBOARD verwendet habe.
    Dann brauche ich eine Message-Loop und eine DLL und bekomme
    dennoch nicht wirklich alle KeyCodes, bzw das Caller Fenster
    muss fokusiert sein.

    Mit WH_KEYBOARD_LL funktioniert das alles wie gewünscht -
    was die Keys angeht. Fensterlos war wohl eine etwas unvorbelastete
    Idee.
    Was das als UI nicht benötigte Fenster angeht,
    mach ich's einfach hidden.

    Gruß,
    Christoph

    Dienstag, 31. August 2010 20:34