15,475
社区成员




代码如下:
static LRESULT CALLBACK explorerProc(int code, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(g_KeyboardHook, code, wParam, lParam);
}
void PcTool::hookexplorertest()
{
HWND e = FindWindow(L"Progman", NULL);
if (e == NULL)
{
e = FindWindow(L"WorkerW", NULL);
}
if (e != NULL)
{
g_KeyboardHook =SetWindowsHookEx(WH_CALLWNDPROC,explorerProc,GetModuleHandle(NULL),
GetWindowThreadProcessId(e, NULL));
if (g_KeyboardHook == nullptr)
{
qDebug() << "----------------------- explorerProc:" << GetLastError();
}
}
}
我的代码写在了应用程序中,应该是要写在dll里
错误码 1428 在 Windows API 调用中通常与 SetWindowsHookEx 函数相关,具体指的是 ERROR_HOOK_NEEDS_HMOD,意味着在尝试安装钩子时,提供的钩子过程(callback function)没有与包含它的 DLL 模块的句柄相关联。
在使用 SetWindowsHookEx 时,如果钩子过程(即你的回调函数)位于一个 DLL 中,你需要确保 SetWindowsHookEx 的第三个参数(hMod)是包含该钩子过程的 DLL 的模块句柄。如果钩子过程位于当前进程的可执行文件中,你应该传递 NULL 作为 hMod 参数。
然而,在你的代码中,你使用了 GetModuleHandle(NULL),这实际上返回的是当前进程的基地址(即主可执行文件的句柄)。如果你的 explorerProc 回调函数确实位于你的主可执行文件中,那么使用 GetModuleHandle(NULL) 是正确的。但如果 explorerProc 位于另一个 DLL 中,你需要传递那个 DLL 的句柄。
但是,这里有一个常见的误解:WH_CALLWNDPROC 钩子通常不用于 DLL 中的钩子过程,因为它们主要设计用于调试目的,并且需要特殊的设置和权限。此外,WH_CALLWNDPROC 钩子并不特别针对某个窗口,而是全局的,对所有窗口的消息处理过程进行监视。
如果你的目的是监视或修改特定窗口(如 Explorer 窗口)的消息,你可能需要考虑以下替代方案:
子类化窗口:通过子类化目标窗口,你可以拦截并修改发送到该窗口的消息。这通常比使用全局钩子更安全、更直接。
使用 UI 自动化:UI 自动化提供了一种强大的方式来与 Windows 应用程序进行交互,包括 Explorer。你可以使用它来模拟用户输入、读取屏幕上的文本等。
重新考虑全局钩子:如果你确实需要使用全局钩子,并且确信你的应用程序有适当的权限,那么请确保你的钩子过程位于正确的位置(DLL 或主可执行文件),并且你正确地传递了模块句柄。
检查权限:确保你的应用程序以管理员身份运行,因为安装全局钩子通常需要这些权限。
调试和日志记录:在你的钩子函数中添加日志记录语句,以帮助你确定何时以及为什么钩子没有被正确安装。
如果你决定继续使用全局钩子,并且 explorerProc 确实位于你的主可执行文件中,那么你应该检查其他可能导致 SetWindowsHookEx 失败的原因,如内存不足、钩子链已满等。但是,请注意,由于 WH_CALLWNDPROC 钩子的特殊性和潜在的安全风险,它可能不是实现你目标的最佳选择。