C#hook钩子对第三方窗体进行获取消息问题记录

有个进口设备由上位机控制,厂家不配合进行自动化改造,每次启动都需要人为手动操作

为了实现自动化采用外挂程序实现事件监控(hook)和运行控制(win32api)

win32api很简单可以向需要的窗口发送消息,控制点击等操作

设置hook

Process currentProcess = Process.GetCurrentProcess();
ProcessModule mainModule = currentProcess.MainModule;
IntPtr moduleHandle = Win32Api.GetModuleHandle(mainModule.ModuleName);
hHook = Win32Api.SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookDelegate, moduleHandle, 0);

SetWindowsHookEx原型

第三个参数为实例句柄,不是窗口句柄

HHOOK WINAPI SetWindowsHookEx(
__in int idHook, \\钩子类型
__in HOOKPROC lpfn, \\回调函数地址
__in HINSTANCE hMod, \\实例句柄
__in DWORD dwThreadId); \\线程ID

实例句柄和窗口句柄

通过SPY++可以看到实例句柄和窗口句柄不是同一个东西

GetModuleHandle为什么不是目标进程

那我们获取一下

IntPtr moduleHandle = IntPtr.Zero;
string tempName = "";
foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
{
    tempName = thisProc.ProcessName;
    if (tempName.Contains("test2Windows"))
    {
        moduleHandle = GetModuleHandle(thisProc.MainModule.ModuleName);// thisProc.MainModule.BaseAddress

         hookID = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, moduleHandle , 0);
        if (hookID == IntPtr.Zero)
        {
            int errorCode = Marshal.GetLastWin32Error();
            Console.WriteLine(errorCode);
 根据错误代码进行错误处理
        }
        break;
    }
}

运行后发现GetModuleHandle结果为NULL(0),原来GetModuleHandle只有在当前进程的场景中,获取句柄才会有效

用其他方法获取实例句柄

GetWindowLong

IntPtr hInstance = GetWindowLong(hWnd, GWL_HINSTANCE);

运行后发现hInstance!=0,hookID=0,errorCode=126-找不到指定的模块。

把hwnd换成该进程自己的窗口句柄发现正常运行,回调函数也正常进入

SetWindowsHookEx局限

        private const int WH_MIN = (-1);
        private const int WH_MSGFILTER = (-1);
        private const int WH_JOURNALRECORD = 0;
        private const int WH_JOURNALPLAYBACK = 1;
        private const int WH_KEYBOARD = 2;
        private const int WH_GETMESSAGE = 3;
        private const int WH_CALLWNDPROC = 4;
        private const int WH_CBT = 5;
        private const int WH_SYSMSGFILTER = 6;
        private const int WH_MOUSE = 7;
        //_WIN32_WINDOWS
        private const int WH_HARDWARE = 8;
        private const int WH_DEBUG = 9;
        private const int WH_SHELL = 10;
        private const int WH_FOREGROUNDIDLE = 11;
        // (WINVER >= 0x0400)
        private const int WH_CALLWNDPROCRET = 12;

        //(_WIN32_WINNT >= 0x0400)
        private const int WH_KEYBOARD_LL = 13;
        private const int WH_MOUSE_LL = 14;

#if WINVER_0400
        public const int WH_MAX = 14;
#elif WINVER_0500
        public const int WH_MAX = 12;
#else
        public const int WH_MAX = 11;
#endif

修改钩子类型为其他类型发现只有13、14键盘和鼠标两种类型可以成功,其他hookID和errorCode都等于0

总结:

1、GetModuleHandle只有在当前进程的场景中,获取句柄才会有效

2、GetWindowLong可以获取其他进程的实例句柄

3、SetWindowsHookEx只能设置钩子到本进程实例句柄中

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值