Condividi tramite


Funzione SetWindowsHookExW (winuser.h)

Installa una routine hook definita dall'applicazione in una catena di hook. Si installerebbe una procedura hook per monitorare il sistema per determinati tipi di eventi. Questi eventi sono associati a un thread specifico o a tutti i thread nello stesso desktop del thread chiamante.

Sintassi

HHOOK SetWindowsHookExW(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);

Parametri

[in] idHook

Tipo: int

Tipo di procedura hook da installare. Questo parametro può essere uno dei valori seguenti.

Valore Significato
WH_CALLWNDPROC
4

Installa una procedura hook che monitora i messaggi prima che il sistema li invii alla procedura della finestra di destinazione. Per altre informazioni, vedere la procedura di hook CallWndProc.

WH_CALLWNDPROCRET
12

Installa una procedura hook che monitora i messaggi dopo che sono stati elaborati dalla procedura della finestra di destinazione. Per altre informazioni, vedere la funzione di callback HOOKPROC procedura hook.

WH_CBT
5

Installa una procedura hook che riceve notifiche utili per un'applicazione CBT. Per altre informazioni, vedere la procedura di hook CBTProc .

WH_DEBUG
9

Installa una procedura hook utile per il debug di altre procedure hook. Per altre informazioni, vedere la procedura hook DebugProc.

WH_FOREGROUNDIDLE
11

Installa una procedura hook che verrà chiamata quando il thread in primo piano dell'applicazione sta per diventare inattiva. Questo hook è utile per eseguire attività con priorità bassa durante il tempo di inattività. Per altre informazioni, vedere la procedura hook ForegroundIdleProc.

WH_GETMESSAGE
3

Installa una procedura hook che monitora i messaggi inviati a una coda di messaggi. Per altre informazioni, vedere la procedura GetMsgProc.

WH_JOURNALPLAYBACK
1

Avvertimento

Le API hook del journaling non sono supportate a partire da Windows 11 e verranno rimosse in una versione futura. Per questo motivo, è consigliabile chiamare invece l'API SendInput TextInput.

Installa una procedura hook che pubblica i messaggi registrati in precedenza da una procedura hook WH_JOURNALRECORD. Per altre informazioni, vedere la procedura hook JournalPlaybackProc.

WH_JOURNALRECORD
0

Avvertimento

Le API hook del journaling non sono supportate a partire da Windows 11 e verranno rimosse in una versione futura. Per questo motivo, è consigliabile chiamare invece l'API SendInput TextInput.

Installa una procedura hook che registra i messaggi di input inviati alla coda dei messaggi di sistema. Questo hook è utile per registrare macro. Per altre informazioni, vedere la procedura hook JournalRecordProc.

WH_KEYBOARD
2

Installa una procedura hook che monitora i messaggi di sequenza di tasti. Per altre informazioni, vedere la procedura KeyboardProc.

WH_KEYBOARD_LL
13

Installa una procedura hook che monitora gli eventi di input della tastiera di basso livello. Per altre informazioni, vedere la procedura hook LowLevelKeyboardProc.

WH_MOUSE
7

Installa una procedura hook che monitora i messaggi del mouse. Per altre informazioni, vedere la procedura MouseProc.

WH_MOUSE_LL
14
Installa una procedura hook che monitora gli eventi di input del mouse di basso livello. Per altre informazioni, vedere la procedura hook LowLevelMouseProc.
WH_MSGFILTER
-1

Installa una routine hook che monitora i messaggi generati in seguito a un evento di input in una finestra di dialogo, una finestra di messaggio, un menu o una barra di scorrimento. Per altre informazioni, vedere la procedura hook MessageProc.

WH_SHELL
10

Installa una procedura hook che riceve notifiche utili per le applicazioni della shell. Per altre informazioni, vedere la procedura hook ShellProc .

WH_SYSMSGFILTER
6
Installa una routine hook che monitora i messaggi generati in seguito a un evento di input in una finestra di dialogo, una finestra di messaggio, un menu o una barra di scorrimento. La procedura hook monitora questi messaggi per tutte le applicazioni nello stesso desktop del thread chiamante. Per altre informazioni, vedere la procedura di hook SysMsgProc.

[in] lpfn

Tipo: HOOKPROC

Puntatore alla routine hook. Se il parametro dwThreadId è zero o specifica l'identificatore di un thread creato da un processo diverso, il parametro lpfn deve puntare a una routine hook in una DLL. In caso contrario, lpfn può puntare a una routine hook nel codice associato al processo corrente.

[in] hmod

Tipo: HINSTANCE

Handle della DLL contenente la procedura hook a cui punta il parametro lpfn. Il parametro hMod deve essere impostato su NULL se il parametro dwThreadId specifica un thread creato dal processo corrente e se la routine hook si trova all'interno del codice associato al processo corrente.

[in] dwThreadId

Tipo: DWORD

Identificatore del thread a cui deve essere associata la routine hook. Per le app desktop, se questo parametro è zero, la procedura hook è associata a tutti i thread esistenti in esecuzione nello stesso desktop del thread chiamante. Per le app di Windows Store, vedi la sezione Osservazioni.

Valore restituito

Tipo: HHOOK

Se la funzione ha esito positivo, il valore restituito è l'handle della routine hook.

Se la funzione ha esito negativo, il valore restituito è NULL. Per ottenere informazioni estese sull'errore, chiamare GetLastError.

Osservazioni

SetWindowsHookEx può essere usato per inserire una DLL in un altro processo. Non è possibile inserire una DLL a 32 bit in un processo a 64 bit e non è possibile inserire una DLL a 64 bit in un processo a 32 bit. Se un'applicazione richiede l'uso di hook in altri processi, è necessario che una chiamata di applicazione a 32 bit SetWindowsHookEx per inserire una DLL a 32 bit in processi a 32 bit e una chiamata dell'applicazione a 64 bit SetWindowsHookEx per inserire una DLL a 64 bit in processi a 64 bit. Le DLL a 32 bit e a 64 bit devono avere nomi diversi.

Poiché gli hook vengono eseguiti nel contesto di un'applicazione, devono corrispondere al "bitness" dell'applicazione. Se un'applicazione a 32 bit installa un hook globale in Windows a 64 bit, l'hook a 32 bit viene inserito in ogni processo a 32 bit (si applicano i normali limiti di sicurezza). In un processo a 64 bit, i thread vengono ancora contrassegnati come "collegati". Tuttavia, poiché un'applicazione a 32 bit deve eseguire il codice hook, il sistema esegue l'hook nel contesto dell'app di hook; in particolare, nel thread che ha chiamato SetWindowsHookEx. Ciò significa che l'applicazione di hook deve continuare a pompare i messaggi o potrebbe bloccare il normale funzionamento dei processi a 64 bit.

Se un'applicazione a 64 bit installa un hook globale in Windows a 64 bit, l'hook a 64 bit viene inserito in ogni processo a 64 bit, mentre tutti i processi a 32 bit usano un callback all'applicazione di hook.

Per associare tutte le applicazioni sul desktop di un'installazione di Windows a 64 bit, installare un hook globale a 32 bit e un hook globale a 64 bit, ognuno dei processi appropriati e assicurarsi di mantenere i messaggi di pompa nell'applicazione hooking per evitare il blocco del normale funzionamento. Se si dispone già di un'applicazione di hook globale a 32 bit e non è necessario eseguirla nel contesto di ogni applicazione, potrebbe non essere necessario creare una versione a 64 bit.

È possibile che si verifichi un errore se il parametro hMod è NULL e il parametro dwThreadId è zero o specifica l'identificatore di un thread creato da un altro processo.

Chiamare la funzione CallNextHookEx funzione per concatenare la routine hook successiva è facoltativa, ma è altamente consigliabile; in caso contrario, altre applicazioni che hanno installato hook non riceveranno notifiche hook e potrebbero comportarsi in modo non corretto di conseguenza. È consigliabile chiamare CallNextHookEx a meno che non sia assolutamente necessario impedire che la notifica venga visualizzata da altre applicazioni.

Nelle app .NET è necessario assicurarsi che il callback non venga spostato da Garbage Collector. In caso contrario, l'app si arresterà in modo anomalo con ExecutionEngineException. Un modo per eseguire questa operazione consiste nel rendere il callback un metodo statico della classe.

Prima di terminare, un'applicazione deve chiamare la funzione funzione UnhookWindowsHookEx per liberare le risorse di sistema associate all'hook.

L'ambito di un hook dipende dal tipo di hook. Alcuni hook possono essere impostati solo con ambito globale; altri possono anche essere impostati solo per un thread specifico, come illustrato nella tabella seguente.

Uncino Portata
WH_CALLWNDPROC Thread o globale
WH_CALLWNDPROCRET Thread o globale
WH_CBT Thread o globale
WH_DEBUG Thread o globale
WH_FOREGROUNDIDLE Thread o globale
WH_GETMESSAGE Thread o globale
WH_JOURNALPLAYBACK Solo globale
WH_JOURNALRECORD Solo globale
WH_KEYBOARD Thread o globale
WH_KEYBOARD_LL Solo globale
WH_MOUSE Thread o globale
WH_MOUSE_LL Solo globale
WH_MSGFILTER Thread o globale
WH_SHELL Thread o globale
WH_SYSMSGFILTER Solo globale
 

Per un tipo di hook specificato, gli hook del thread vengono chiamati prima, quindi hook globali. Tenere presente che i WH_MOUSE, WH_KEYBOARD, WH_JOURNAL*, WH_SHELL e hook di basso livello possono essere chiamati sul thread che ha installato l'hook anziché sul thread che elabora l'hook. Per questi hook, è possibile che entrambi gli hook a 32 bit e a 64 bit vengano chiamati se un hook a 32 bit è davanti a un hook a 64 bit nella catena di hook.

Gli hook globali sono una risorsa condivisa e l'installazione di una influisce su tutte le applicazioni nello stesso desktop del thread chiamante. Tutte le funzioni hook globali devono trovarsi nelle librerie. Gli hook globali devono essere limitati alle applicazioni per scopi speciali o da usare come supporto per lo sviluppo durante il debug dell'applicazione. Le librerie che non necessitano più di un hook devono rimuovere la procedura hook.

app di Windows Store: Se dwThreadId è zero, le DLL hook finestra non vengono caricate in-process per i processi dell'app di Windows Store e il processo broker di Windows Runtime, a meno che non siano installati da uno dei processi uiAccess (strumenti di accessibilità). La notifica viene recapitata nel thread del programma di installazione per questi hook:

  • WH_JOURNALPLAYBACK
  • WH_JOURNALRECORD
  • WH_KEYBOARD
  • WH_KEYBOARD_LL
  • WH_MOUSE
  • WH_MOUSE_LL
Questo comportamento è simile a quello che accade quando si verifica una mancata corrispondenza dell'architettura tra la DLL hook e il processo dell'applicazione di destinazione, ad esempio quando la DLL hook è a 32 bit e il processo dell'applicazione a 64 bit.

Esempi

Per un esempio, vedere Installazione e rilascio di procedure hook.

Nota

L'intestazione winuser.h definisce SetWindowsHookEx come alias che seleziona automaticamente la versione ANSI o Unicode di questa funzione in base alla definizione della costante del preprocessore UNICODE. La combinazione dell'utilizzo dell'alias indipendente dalla codifica con il codice non indipendente dalla codifica può causare mancate corrispondenze che generano errori di compilazione o di runtime. Per altre informazioni, vedere convenzioni di per i prototipi di funzioni.

Fabbisogno

Requisito Valore
client minimo supportato Windows 2000 Professional [solo app desktop]
server minimo supportato Windows 2000 Server [solo app desktop]
piattaforma di destinazione Finestre
intestazione winuser.h (include Windows.h)
libreria User32.lib
dll User32.dll
set di API ext-ms-win-ntuser-window-l1-1-0 (introdotto in Windows 8)

Vedere anche

funzione CallNextHookEx

funzione CallWindowProc

funzione UnhookWindowsHookEx

CBTProc

CallWndProc

CallWndRetProc

DebugProc

ForegroundIdleProc

GetMsgProc

JournalPlaybackProc

JournalRecordProc

KeyboardProc

LowLevelKeyboardProc

LowLevelMouseProc

MessageProc

MouseProc

ShellProc

SysMsgProc

concettuale

hook