问题
I have created a global Keyboard hook.
Hook is created in a DLL.
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
static HHOOK hkb=NULL;
static CMyFile *pLF;
#pragma data_seg()
HINSTANCE hins = NULL;
extern "C"
LRESULT __declspec(dllexport) __stdcall CALLBACK KeyBoardHookProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
if (nCode < 0) {
return CallNextHookEx(0, nCode, wParam, lParam);
}
return CallNextHookEx(hkb, nCode, wParam, lParam);
}
extern "C"
LRESULT __declspec(dllexport) __stdcall CALLBACK Install()
{
pLF = new CMyFile(L"c:\\1.txt");
hkb = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyBoardHookProc,hins,0);
return 0;
}
extern "C"
BOOL __declspec(dllexport) __stdcall CALLBACK UnInstall()
{
return UnhookWindowsHookEx(hkb);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH :
hins = (HINSTANCE) hModule;
break;
case DLL_THREAD_ATTACH :
break;
case DLL_THREAD_DETACH :
break;
case DLL_PROCESS_DETACH :
break;
}
return TRUE;
}
I have craeted one EXe that loads this dll and calls install function of the hook dll.
HMODULE hMod = LoadLibrary(L"hk.dll");
if(hMod!=NULL)
{
typedef LRESULT (__stdcall CALLBACK *_installhk)() ;
_installhk installProc;
installProc = (_installhk) GetProcAddress(hMod,"Install");
if(installProc!=NULL)
{
installProc();
}
}
While debugging breakpoint on KeyBoardHookProc is being hit only once when I launch the exe.
The exe keeps on running unless I close it but if I enter anything else from keyboard the hook procedure not getting called.
What could be the reason for this?
Is this not the right way to setup global keyboard hook?
回答1:
How did you test that the hook procedure is not called ? If you tried to check it with a breakpoint, you have to take care that your hook dll is loaded in every process but your breakpoint is only put in your current process.
If you have any window in your application, focus on it before hitting keys or debug it using logs.
Another solution is to hook with WH_KEYBOARD_LL which does not require an extra DLL. You can hook directly from your process.
回答2:
Have a look at the late Paul DiLascia's code which installs a global keyboard hook to trap the Ctrl+Alt+Del, Task Manager. MSDN September 2002 'Disabling keys in XP with TrapKeys'
Hope this helps, Best regards, Tom.
回答3:
This may not be directly related to your main problem, but your use of the CMyFile object has several issues:
The CMyFile object is allocated dynamically using
new CMyFile(...)
. This will create it only in the memory space of one process.The
pLF
pointer is uninitialized. This means it will be placed in the BSS segment instead of the shared data segment. To fix this, declare it withCMyFile *pLF = NULL;
.CMyFile itself probably has members containing file handles and/or pointers which won't work properly in other processes.
Regarding your main question:
You seem to be creating the hook correctly as far as I can see.
There is no need to cast to HOOKPROC in the call to SetWindowsHookEx. If you get a warning without it, there is a problem with your function type.
There's no need for the
if
statement in the hook proc - the first parameter to CallNextHookEx is ignored anyway on modern Windows, so both branches effectively do the same thing.I don't know if I'd trust debugger breakpoints on a hook procedure called from different processes - it's possible that the procedure is called but the debugger isn't catching it.
回答4:
extern "C"
is good it will get rid of the name mangling mentioned above but __stdcall
will conflict with this.
回答5:
You should use the RegisterHoyKey API call instead - it's much less hassle (as I found out myself recently when I replaced a similar keyboard hook DLL!).
回答6:
Check your export section for DLL and see what name linker exported your "Install" function. C++ mangles with export function names. I bet you anything it is not "Install" but rather _Install@12 or something like that.
来源:https://stackoverflow.com/questions/2127112/global-keyboard-hook-not-working