Click here to Skip to main content
15,860,859 members
Articles / Programming Languages / C#
Article

Hooking in Microsoft .NET

Rate me:
Please Sign up or sign in to vote.
3.81/5 (12 votes)
27 Jun 20073 min read 53.7K   1.3K   58   10
An article discussing hook implementation in .NET

Win32 hooks: a refresher

The Win32 hook is a mechanism by which user-defined functions can be intercepted before an event reaches the target application. Hooks decreases system performance due to the additional processing required for each message. So, they should be installed only when necessary and uninstalled as soon as possible.

Microsoft Windows supports many types of hooks, like WH_KEYBOARD, which can be used for hooking the keyboard. Each type of hook provides access to different types of messages. The system maintains a data structure called a hook chain for each type of hook. This chain is a list of pointers to functions called hook procedures. Some types of hooks can only monitor messages; others can modify messages or stop their progress through the chain, preventing them from reaching the next hook procedure or the destination window.

The prototype of the hook procedure varies a bit according to the type of message it is expected to catch. Applications install hooks using the SetWindowsHookEx API and UnhookWindowsHookEx is used for uninstalling the same.

C#
HHOOK SetWindowsHookEx (int idHook, 
    HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);

The first parameter above specifies the hook ID, e.g. WH_KEYBOARD for hooking the keyboard, WH_MOUSE for hooking the mouse. The second parameter is the hook procedure that will be called when the particular message gets fired. The third parameter is the instance/module handle where the hook procedure is defined. The last parameter specifies the window thread to be hooked. This can be retrieved using the API GetWindowThreadProcessId for passing the window handle. If this parameter is empty, then this will install a system hook. For more information, refer to this MSDN article.

Global hooks are not supported in .NET. This behavior requires a DLL export and .NET Framework does not support DLL exports.

Hooks in .NET

There is no built-in support for hooks in Microsoft .NET; P/Invoke is used to handle such things. P/Invoke is a method of calling unmanaged APIs. In .NET, the smallest units of processing are Application Domains -- called AppDomains for short -- whereas in Win32, the smallest unit of processing is a process. So, we make use of the SetWindowsHookEx API through the P/Invoke method to install hooks and we use UnhookWindowsHookEx for uninstalling the hooks.

How the code works

The sample application with this article contains a class called Win32Hook that is a simple wrapper for handling the hook. The function InstallHook installs a WH_GETMESSAGE type hook.

C#
public bool InstallHook()

This function returns true if the hook is installed successfully. Next, the function...

C#
public bool UninstallHook () 

...uninstalls the hook. Don't forget to call this after you have done with it.

C#
m_oHookManager.HookInvoked+= 
    new Win32Hook.HookEventHandler(m_oHookManager_OnHookMessage);

Here, the method m_oHookManager_OnHookMessage will be called whenever an event is fired on the target window. The function prototype is:

C#
void m_oHookManager_OnHookMessage (object sender, HookEventArgs hea)

The class HookEventArgs is defined in the same file and contains all of the messages related to a message, such as the identifier, whether it is going to be removed from the queue (PM_REMOVE or PM_NOREMOVE), etc.

C#
[DllImport ("user32.dll")]
private static extern IntPtr SetWindowsHookEx(HookId hookId, HProc hookProc,
    IntPtr hInstance, Int32 threadId);

[DllImport ("user32.dll")]
private static extern Int32 UnhookWindowsHookEx(IntPtr hHook);

[DllImport ("user32.dll")]
private static extern Int32 CallNextHookEx(IntPtr hHook, Int32 nCode,
    IntPtr wParam, IntPtr lParam); 

The DllImport attribute specifies the DLL where the function is defined. This attribute is defined in System.Runtime.InteropServices. For more information, refer to this MSDN article. It might take a long time to implement hooks in Microsoft .NET due to the architectural changes introduced in the native to managed code transition.

History

  • 27 June, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Technical Lead
India India
Sudeesh

Comments and Discussions

 
QuestionI have a question... Pin
mesiasrojo11-Aug-11 0:29
mesiasrojo11-Aug-11 0:29 
AnswerHow to Hook for a new process creation using API in .net Pin
MayankNainwal5-Mar-12 19:45
MayankNainwal5-Mar-12 19:45 
Generallocal variable Pin
Andy Brummer18-Jun-08 10:58
sitebuilderAndy Brummer18-Jun-08 10:58 
GeneralRemove a message from message queue. Pin
tarantula321-Sep-07 13:54
tarantula321-Sep-07 13:54 
GeneralRe: Remove a message from message queue. Pin
sudeesh27-Nov-07 2:44
sudeesh27-Nov-07 2:44 
Generali want to capture all webcontrols of other website Pin
Rohituappu11-Jul-07 19:56
Rohituappu11-Jul-07 19:56 
GeneralHook into MSN Messenger Pin
johnnycantcode27-Jun-07 7:21
johnnycantcode27-Jun-07 7:21 
AnswerRe: Hook into MSN Messenger [modified] Pin
sudeesh28-Jun-07 18:14
sudeesh28-Jun-07 18:14 
GeneralRe: Hook into MSN Messenger Pin
johnnycantcode8-Jul-07 9:09
johnnycantcode8-Jul-07 9:09 
GeneralRe: Hook into MSN Messenger Pin
sudeesh9-Jul-07 1:25
sudeesh9-Jul-07 1:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.