We help IT Professionals succeed at work.

SetWindowsHookEx not working with  x64 OS

ICSAutomation asked
I had a C# application on VS2003, running on XP and WinServer2003 (both x86 OS).
In this application I use the hook "SetWindowsHookEx" to detect user activities and make a auto logout.

I migrated the application to VS2010 (.Net4.0) which I run on WinServer2008R2 and Win7prof, both running on x64 machines. The target platform of the application is still x86.

Unfortunately, the "SetWindowsHookEx" is not working any more :-(

What could be the reason?

Thanks for any help!!
Watch Question

ste5anSenior Developer

So, you're getting NULL as result. And what error code do you get (GetLastError)?


Sorry, I should have explaned a bit more exactly...
What I analysed so far:
- the Hook could be set:
************  Code *********
                // Create an instance of HookProc.
                MouseHookProcedure = new HookProc(MouseHookProc);
                //install hook
                hMouseHook = SetWindowsHookEx(
- the procedure "MouseHookProc" is called the first time I mouve the mouse
- but after the hook called "MouseHookProc" once, it is not called any more.....
- I don't gett any exception or error code...
ste5anSenior Developer
Have you checked the value in hMouseHook after the function call?

Also, where does Assembly.GetExecutingAssembly().GetModules()[0] point to? I'm quite sure that this does not return the correct thread id. See SetWindowsHookEx function.  I would expect it to be zero or the thread ID of your UI thread.

btw, in .NET I would try to solve this with an IMessageFilter.
Top Expert 2016
To hook all applications on the desktop of a 64-bit Windows installation, install a 32-bit global hook and a 64-bit global hook, each from appropriate processes, and be sure to keep pumping messages in the hooking application to avoid blocking normal functioning. If you already have a 32-bit global hooking application and it doesn't need to run in each application's context, you may not need to create a 64-bit version.


Sorry, I was out of the office for a few days...

>>>> Have you checked the value in hMouseHook after the function call?
 Yes, hMouseHook  is 197329197 ( a different nuber after every start). Could this be the thread ID?

>>>> Also, where does Assembly.GetExecutingAssembly().GetModules()[0] point to?
It points to my applicaiton, but I don't see a thread Id in the modul data (see picture)

If I call later "CallNextHookEx" it returns my the value 0.

>>>> btw, in .NET I would try to solve this with an IMessageFilter.
I cannot use IMessageFilter because I want to get the event, also if the focus is not on my application.
Senior Developer
Forget the IMessageFilter, this was nonsense. But I was right about the thread ID. You need the ID of your thread from the app domain:

hHook = SetWindowsHookEx(WH_MOUSE, 

Open in new window

See also this example:

How to set a Windows hook in Visual C# .NET


Thanks for your answer!!

I need to install a low-level mouse input (WH_MOUSE_LL) which is also activated if the focus is not on my application.
(the example shows only mouse monitoring in the application)

I implemented it like this:
It was working fine in my old x32 Windows Server 2003 and the old WinXP environement. (two devices)
But since I replaced the hardware to a virtual x64 Windows Server and virtual Windows7 envirtonements, the hook does not work properly any more :-(


This was not the final solution, but I got some good inputs. Thanks!!
I finally found a solution, without using "SetWindowsHookEx"