Click here to Skip to main content
15,042,397 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hi. At first sorry for my English.

I have a problem with keyboard hooking. I made a small program that hooks the keyboard. It works in my computer, but if I run on another computer it works only if the application's window is focused. I found a lot of topics with this question, but none of them helped. I made a DLL file with the hook procedure, and I start hooking with an exe file. I have also a DEF file with exports so I can load the procedures from DLL, the only problem is that it's not works in other computers. I don't know if somebody faced this problem, but I hope that somebody can help me.

I'm using Visual Studio 2010 and Windows 7 Ultimate x64

And a remark: the hook dll is loaded only to hooker process.

Here is my source code:
DLL:
C++
#include <Windows.h>

#pragma data_seg("Shared")
HHOOK hHook = NULL;
#pragma data_seg()

HINSTANCE hInstance = NULL;

void __stdcall Install();
void __stdcall Remove();

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch(ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		hInstance = (HINSTANCE)hModule;
		break;
	case DLL_PROCESS_DETACH:
		Remove();
		break;
	}
	
	return TRUE;
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	// processing data
	return CallNextHookEx(hHook, nCode, wParam, lParam);
}

void __stdcall Install()
{
	if(hHook == NULL)
	{
		hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, hInstance, 0);

	}
}

void __stdcall Remove()
{
	if(hHook != NULL)
		UnhookWindowsHookEx(hHook);
	
	hHook = NULL;
}


Hooker exe:
C++
#include <Windows.h>

typedef void (__stdcall *FuncPtr)(void);

int main()
{
	FuncPtr Install;
	HMODULE hmodDll = LoadLibrary("DLL.dll");
	MSG Msg;
	if(hmodDll == NULL)
		return -1;
	Install = (FuncPtr)GetProcAddress(hmodDll, "Install");
	if(Install == NULL)
		return -2;

	Install();

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return 0;
}


P.S.
This is just an experiment.
Posted
Updated 6-Jun-13 8:54am
v2
Comments
   
Indeed, it looks strange, this difference between two different systems. Your question is formulated quite accurately, thank you. Except one thing: how did you observe your "it works only if..."?
You did not explain what do you mean by working; probably, something could happen under "// processing data" you commented out. I know that debugging hooks is not very easy, so the problem could lie in the observation of "working" or "not working". Could you think of some 100% reliable test of "working", code it and observe again. Could you also tell use what is that effect to be "working"?
The problem is the thread executing KeyboardProc is uncertain, so the code you call from this function should be something really IPC.
—SA
szabolcsx 6-Jun-13 16:02pm
   
You're right. By "working" I mean that when the user press a key in keyboard, the KeyboardProc gets executed. By the way the program works in my computer as I mentioned above. If I press a button in keyboard whatever what window is focused, the KeyboardProc gets executed. I know, because the commented part of the process also gets executed and does his work. But when I move the program to an other PC, the KeyboardProc gets executed only if I press some buttons in keyboard while the hooker process (the console window of hooker process) is focused. If that window lose the focus, the KeyboardProc will not be called until the hooker window gains the focus again. In the other hand, I modified the KeyboardProc to print some messages if gets executed, but I faced the same problem.
   
I understand that. This is the whole point: I'm asking how do you know that this commented part is executed and what is it. "To print some messages" is one of the unreliable criteria.
Look, if you have some apparently mysterious behavior, everything can be a suspect. And you "print some messages" is more likely than anything else I can see so far...
Do you see the point?
—SA
Maciej Los 6-Jun-13 17:22pm
   
A 5 for question!

1 solution

Please see my comments to the question and think about it.

For first step, please try the following: instead of "printing some messages", do the following: send Beep to the speaker (first, make sure it works in a "normal" application), something like:

C++
#include <windows.h>

//...

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    Beep(440, 400); // A440, 440 Hz, standard la pitch in modern Western
                    // equal temperament system
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}


I'm not quite joking. I an expecting that you might hear the beep on both computers. I already resolved a number of mysterious "not working" problems using this simple trick.

Well, I might be wrong. In this case, we can think about the next step. But please try this first.

—SA
   
v2
Comments
Maciej Los 6-Jun-13 17:22pm
   
Sergey, i'm not familiar with that, but sounds reasonable...
If OP accept your answer, i'll promise to vote 5. Please, remind me about that, OK?
   
If I remember myself to check it or if OP reminds me by a comment. It's OK...
—SA
Maciej Los 7-Jun-13 1:51am
   
Why to wait?
A 5!
   
Thank you, but OP says it did not beep...
—SA
nv3 7-Jun-13 3:51am
   
Nice debugging trick; certainly worth to remember that one, no matter whether it helps in that particular case or not. +5
   
Thank you; unfortunately, OP says it did not help...
—SA
szabolcsx 7-Jun-13 7:45am
   
Hi, I made the changes as you suggested, but still the same problem. On my PC I hear beeps when I press a keyboard button, on my second PC with Windows XP I don't hear anything unless the hooker console window is focused.
   
Thank you for the feedback...
Different Windows versions, huh? Hard to blame XP; as I worked with global hooks starting from very old versions...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900