SetWindowsHookEx 使用谷歌浏览器失败。错误代码 87 参数无效

Posted

技术标签:

【中文标题】SetWindowsHookEx 使用谷歌浏览器失败。错误代码 87 参数无效【英文标题】:SetWindowsHookEx failing with google chrome. Error code 87 invalid parameter 【发布时间】:2011-05-17 11:19:14 【问题描述】:

我正在制作一个基于教程的程序,并希望能够将我的代码挂接到某些应用程序中,以使教程与应用程序交互。

我的钩子代码适用于除谷歌浏览器之外的大多数应用程序。我已将我的代码精简为以下内容,因此您可以看到它出错了。

Main.cpp

#include <Windows.h>
#include <iostream>
#include <psapi.h>
#include <Tlhelp32.h>

unsigned long GetProcId( const std::string& name )

    unsigned long res = 0 ;

    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32 processInfo ;
    processInfo.dwSize=sizeof(PROCESSENTRY32W);

    if( !Process32First( hSnapShot, &processInfo ) )
    
        CloseHandle( hSnapShot ); 
        return res ;
    

    do 
    
        if( NULL != ( strstr ( strlwr ( processInfo.szExeFile ), name.c_str() ) ) )
                       
            res = processInfo.th32ProcessID ;
            break ;
        
     while(Process32Next( hSnapShot,&processInfo ));

    CloseHandle( hSnapShot ) ;
    return res ;


typedef LRESULT (CALLBACK *DllHookProc)(int nCode, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
               LPSTR lpCmdLine, int nCmdShow)

    unsigned int processid = GetProcId( "chrome.exe" ) ;

    if (processid == 0)
    
        return 0 ;
    

    HINSTANCE dllInstance = LoadLibrary("mydll.dll") ;

    if (dllInstance == NULL)
    
        return 0 ;
    

    DllHookProc hookProc = (DllHookProc)::GetProcAddress(dllInstance, "HookProc");

    if ( hookProc == NULL) 
    
        FreeLibrary(dllInstance);
        return 0 ;
    

    HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)hookProc,
        dllInstance, processid );

    if (hook == NULL)
    
        FreeLibrary(dllInstance);
        return 0 ;
    

    return 0 ;

测试 Dll (mydll.dll)

LRESULT CALLBACK HookProc (int nCode, WPARAM wParam, LPARAM lParam )

    //Pass to the next chain in the process list
    return CallNextHookEx( 0, nCode, wParam, lParam);


BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)

    return TRUE;

定义文件

LIBRARY "MYDLL"
EXPORTS
HookProc @1

一切正常(包括获取 processId 和加载库和 getprocaddress)直到 SetWindowsHookEx 返回 NULL,错误代码为 87(无效参数)。

chrome.exe 和我的代码都是 32 位的。

这对其他人有用吗,或者有谁知道它不起作用吗?

谢谢

【问题讨论】:

【参考方案1】:

您知道 chrome 使用多进程模型,对吧?有许多 chrome 实例合作,其中一些可能没有事件队列。

您的GetProcId 代码肯定不能用于 chrome,因为它只能找到一个匹配的进程。

【讨论】:

【参考方案2】:

一个可能的问题是,如果您正在构建 64 位代码,但 chrome.exe 是 32 位(或相反)。 [查看评论和更新,事实并非如此。]


您的代码中有一个可疑之处是您没有调用Process32First,这似乎是必需的。例如:Taking a Snapshot and Viewing Processes。


最后一个建议:您将进程 ID 传递给 SetWindowsHookEx,但它需要一个线程 ID。

【讨论】:

感谢您的回复,但它们都是 32 位的 Process32First 的好地方。我已经修复了代码,但不幸的是仍然是同样的问题。再次感谢 解决了,非常感谢!但是 chrome 可能有很多线程正在运行,所以有没有办法可以找到主 GUI threadid,所以我知道我的 dll 在退出 chrome 之前不会被卸载?再次感谢您提供了很大的帮助 抱歉,我不知道 - 我实际上并没有在 Windows 上编码 :-) 问一个单独的问题。 “但是 chrome 可能有很多线程正在运行,所以有没有办法找到主 GUI threadid” - 最好的办法是在 Chrome 中找到您感兴趣的 HWND,然后使用GetWindowThreadProcessId 来获取它的 threadId。还建议使用 Spy++ 检查窗口的结构以及哪些进程/线程拥有它们 - 但请注意 Chrome 可能会在未来某个阶段改变它的工作方式。目前看来,chrome 中的所有 HWND 似乎都归同一个线程所有,但某些插件窗口除外。

以上是关于SetWindowsHookEx 使用谷歌浏览器失败。错误代码 87 参数无效的主要内容,如果未能解决你的问题,请参考以下文章

调用 SetWindowsHookEx() 的应用程序能否捕获自动完成 URL 和密码?

为啥必须将 SetWindowsHookEx 与 Windows 消息队列一起使用

google浏览器的问题。在我播放视频或者声音的时候,鼠标点击的位置和实际操作的位置总是有偏差怎么办?

用于 DeviceIOControl 的 SetWindowsHookEx,要使用啥 hookid?

使用 KeyboardProc / SetWindowsHookEx 从注入的 DLL 中挂钩键盘

使用 SetWindowsHookEx 时灵敏度下降