Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

Global hook con C# e Visual Studio 2005

Questa la considero una notizia molto importante, perchè da quando mi ero messo in testa di realizzare Happy Sign che volevo riuscirci, e questa mattina ho avuto la soluzione. Dunque, il tema è quello di realizzare un global hook sulla tastiera.

A cosa serve? Beh, senza scendere troppo in dettaglio, si tratta di un meccanismo tramite il quale una nostra applicazione può intercettare tutti gli eventi di tastiera e mouse anche se la nostra applicazione non ha il focus. Il mio Happy Sign ne aveva bisogno perchè volevo fare in modo di poter inserire una firma dentro Outlook Express (o Thunderbird, per par-condicio) semplicemente premendo una combinazione, come Shift+F5, per esempio. Beh, insomma, sembrava che questa cosa con VS2005 fosse impossibile. Il codice che avevo usato, o che ho riesumato fuori questa mattina, è il seguente:

public void Start()
{            
    
// install Keyboard hook 
    
if(hKeyboardHook == 0)
    {
        KeyboardHookProcedure = 
new HookProc(KeyboardHookProc);
        hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,
            KeyboardHookProcedure, 
            Marshal.GetHINSTANCE(
            Assembly.GetExecutingAssembly().GetModules()[0]),
            0);

        
//If SetWindowsHookEx fails.
        
if(hKeyboardHook == 0 )    {
            Stop();
            
throw new Exception("SetWindowsHookEx ist failed.");
        }
    }
}

Questo metodo Start è incluso in una classe apposita UserActivityHook. Se provate a compilarlo con VS2005, tutto ok. Ma è in fase di run-time che la chiamata a SetWindowsHookEx fallisce, e l'hook di fatto non viene installato. La chiamata avviene con i seguenti parametri:

hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,
            KeyboardHookProcedure, 
            Marshal.GetHINSTANCE(
            Assembly.GetExecutingAssembly().GetModules()[0]),
            0);

ovvero:

  1. una costante WH_KEYBOARD_DLL che ci dice quale hook vogliamo installare. In questo caso 13.
  2. un delegate, che ci dice quale funzione viene eseguita quando premiamo un tasto
  3. un puntatore all'istanza della nostra applicazione
  4. l'ID del thread che, non so dettagliare ulteriormente, è 0

Risoluzione
Il codice è corretto, se lo provate con VS2003, tutto funziona regolarmente. Con VS2005, banalmente, dobbiamo andare nelle proprietà del progetto, spostarci sotto il tab Debug e disattivare la CheckBox "Enable the Visual Studio hosting process" (enabled by default). Questa risposta, arrivata su un mio post del 25/11/2005 sul newsgroup dotnet.framework.windowsforms di Microsoft, è di un certo Timm Martin e mi ha permesso, finalmente, di avere global hook funzionante in un'applicazione C# 2.0!!!  Il minimo che posso fare è linkare qua il suo sito: http://www.mini-tools.com. Grazie, Timm, ovunque tu sia!

powered by IMHO 1.3

Print | posted on sabato 28 gennaio 2006 12:28 | Filed Under [ I miei freeware Sviluppo .NET ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET