2

我正在编写一个键盘记录器/鼠标跟踪器,用于开源输入热图应用程序,该应用程序与 Razer 最新的热图软件基本相同,但可用于任何硬件/操作系统(使用 Qt 惊人的跨平台 SDK)。正如您想象的那样,当应用程序不是主进程时,这涉及从内核拦截键盘和鼠标消息。

对于 Windows,我被 GetAsyncKeyState 所吸引,但是如果“前台线程属于另一个进程并且桌面不允许挂钩或日志记录”,则MSDN的返回值上有一条关于此函数返回零的注释。

不管怎样,我写了一个获取键盘状态的方法(通过 Qt 的 QTimer 方法触发每个设定的时间间隔),它只是工作:

//The following executes every 100th of a second:
for (int i = 0; i < 256; ++i)
{
    keyboardArray[i] = GetAsyncKeyState(i);
}

当我在调试器中观察这个数组时,即使应用程序不是主进程,我也可以看到数组中的值在我键入时发生变化。所以,对于我的电脑来说,当主线程没有专注于我的应用程序时,至少这个功能可以监控关键状态。

我的问题是:在什么情况下 Windows不允许挂钩或日志记录?换句话说,是否存在某些版本的 Windows 和/或用户可能拥有/不拥有的权限,而这种方法可能会失败?我真的无法使用一堆不同的机器来测试它。

我的规格是 Windows 7 Home Premium 64 位、Intel i7 930(2.8 GHz、四核超线程)、12 GB DDR3 1333 MHz 内存、2x Nvidia 460(如果有帮助的话)。

此致,

  • 魏卡泽纳

编辑:

Hans Passant 给了我一个这种类型的实现会失败的例子:主要是 Windows 上包含用户界面特权隔离(UIPI) 的应用程序。基本上,如果应用程序对操作系统非常重要(如命令提示符),那么这种类型的消息拦截将不起作用。我什至对其进行了测试,这是真的:当命令提示符是主线程时,我的应用程序会停止更新键盘数组。

这一点和 LoPiTaL 所说的都表明,只有特定的应用程序才会允许这种类型的拦截发生。我主要将此应用程序针对(像我一样)希望看到按键和鼠标点击以进行游戏的游戏玩家,所以也许我不太关心这个问题,但如果我想将其扩展到一般用途(包括经常使用 CMD 的人)然后似乎实际上没有办法拦截这些类型的提升应用程序的关键消息。

这是真的吗,还是像 SetWindowsHookEx 这样的方法仍然可以拦截到 UIPI 应用程序的消息?我试图避免直接实现挂钩,因为这可能被视为人们家用机器上的病毒,并且捕获并重新发送每条输入消息只会减慢一切,这在游戏中是相当大的。

4

0 回答 0