I was looking at the example in Microsoft KB318804 but they use the threadId of the "current" application!!! I have some C++ code which works but we have to rewrite it, and I would prefer to re-write in C# while I am in there. The one thing it does is get the threadId of the target application like so:
uint lastId = GetWindowThreadProcessId(targetHandle, IntPtr.Zero);
no, GetCurrentThread is not the correct call as I am getting the thread id of a remote application which is what we do today AND what we want to do. targetHandle is a handle to that remote application.
I cast this lastId to an int and tried to wire up C# code but the SetWindowsHookEx returns 0 and fails. Only AppDomain.GetCurrentThreadId() seems to work (even though it is deprecated, the replacement though doesn't work either).
Do I have to go with the C++ code then? or is there a way to get it to work in C#?
Currently we register the hookhandler in C++ with the other application and get events back.
Have you checked out the pinvoke.net entry for SetWindowsHookEx
?
If SetWindowsHookEx
returns NULL
, you are supposed to call GetLastError
, so in C# you should call Marshal.GetLastWin32Error
(Assuming that DllImportAttribute.SetLastError
was included on the P/Invoke signature.)
From pinvoke.net:
Signature
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
Calling
IntPtr hHook;
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
{
IntPtr hModule = GetModuleHandle(module.ModuleName);
hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, hook, hModule, 0);
}
Possibly related questions: