来源出处:本文中文移植自 AutoHotkey 官方论坛 Ruevil2 的帖子 How to Make AHK Work in Most Games - The Basics。原帖最后更新于 2023-01-25。本文按 AHK66 读者习

  • Home
  • 活动速递
  • 如何在大多数游戏中生效:按键、点击和窗口模式排查

来源出处:本文中文移植自 AutoHotkey 官方论坛 Ruevil2 的帖子 How to Make AHK Work in Most Games - The Basics。原帖最后更新于 2023-01-25。本文按 AHK66 读者习惯整理为 AHK v1 方向,保留原帖核心排查思路、代码和部分回复补充。

游戏里 AHK 不生效,是新手经常遇到的问题:热键在记事本里正常,进游戏就没反应;Send 明明执行了,角色却不动;鼠标坐标在桌面正常,进全屏游戏后点偏;脚本刚开始能用,过一会儿又失效。很多时候,这不是代码语法错了,而是游戏输入方式、窗口模式、权限级别和 DirectX 输入轮询机制共同造成的。

这篇文章按“先做简单排查,再逐步加深”的顺序整理。建议不要一上来就怀疑复杂原因,先把管理员权限、窗口模式、按键延迟、游戏内按键绑定这几件事确认清楚。

常用工具

1. AHKInfo / Window Spy

这是最基础的窗口和坐标查看工具。它可以查看窗口标题、类名、进程名、鼠标坐标、像素颜色等信息。排查游戏脚本时,至少要确认当前游戏窗口能不能被识别、坐标模式是否符合预期。

如果你使用本站的 AHKEditor,可以通过里面附带的 AHKInfo 获取窗口信息。

2. Send 和 Click 测试工具

原帖推荐了一个 Send 和 Click 测试工具,用来判断不同发送方式、点击方式在目标游戏中是否有效。它的价值在于:不要凭感觉猜 Send、SendInput、Click、ControlClick 哪个能用,而是直接测试。

原帖链接:Send and Click Tool

第一步:用管理员权限运行脚本

最常见的原因之一,是游戏以管理员权限运行,而你的 AHK 脚本没有管理员权限。Windows 的权限隔离会导致低权限进程无法稳定控制高权限窗口。

最简单的测试方式:右键脚本,选择“以管理员身份运行”。如果这样就能用了,问题基本就是权限级别。

也可以把自提权代码放到脚本开头:

#Requires AutoHotkey v1.1

if !(A_IsAdmin || InStr(DllCall("GetCommandLine", "Str"), ".exe /r"))

RunWait % "*RunAs " (_:=A_IsCompiled ? """" : A_AhkPath " /r """) A_ScriptFullPath (_ ? """" : """ /r")

如果脚本已经编译成 exe,也同样可以右键 exe 以管理员身份运行,或者在兼容性设置里勾选“以管理员身份运行此程序”。

第二步:把游戏改成窗口化或无边框窗口化

原帖建议:把游戏从 Full Screen(独占全屏)切换成 Windowed(窗口化)或 Borderless Windowed(无边框窗口化)。作者个人更推荐无边框窗口化。

原因是很多游戏通过 DirectX 绘制画面。独占全屏下,屏幕内容、鼠标坐标、颜色读取、窗口焦点和输入处理都可能和普通 Windows 窗口不同。常见表现包括:

取色结果不对。

鼠标移动到“错误”的坐标。

ImageSearch、PixelSearch、FindText 找不到目标。

Send 或 Click 执行了,但游戏不接收。

如果一个脚本在桌面程序里正常,在游戏里异常,第一轮排查就应该先测试窗口化模式。

第三步:按键按下时间要更长

很多游戏不是像普通文本框那样接收瞬间按键,而是通过 DirectInput 或类似机制周期性轮询键盘状态。可以简单理解为:游戏每隔一段时间拍一张“当前按键状态快照”,再和上一张快照比较,判断哪些键被按下、松开、保持按住。

如果 AHK 发送的按下和松开太快,刚好落在两次快照之间,游戏就可能完全没看到这次按键。

原帖提到一些游戏的轮询间隔可能是 10ms、15ms,格斗游戏还可能和帧率同步。实际脚本里,20ms 是一个可以先尝试的值;有些游戏需要 50ms、100ms,甚至更长。

Send, {a down}

Sleep, 20

Send, {a up}

如果 20ms 不稳定,可以逐步加大:

Send, {a down}

Sleep, 50

Send, {a up}

论坛回复里 evilC 补充过一个判断方法:如果游戏有聊天框或输入框,发送的按键能出现在聊天框里,但不能触发游戏动作,那么很可能是按键延迟不够,游戏动作层没有捕捉到这次按键。

也可以全局设置按键延迟:

SetKeyDelay, 0, 50

Send, a

第四步:不要抢游戏已经占用的按键

有些游戏不允许自己的按键绑定被 AHK “接管”。尤其是 DirectX 驱动的游戏,可能使用更底层的键盘交互方式。此时你按下某个键,游戏优先拿走了这个键,AHK 热键就不稳定,或者完全触发不了。

解决思路是:尽量选择游戏没有使用的按键作为 AHK 热键。也可以在游戏设置里修改键位,把某些键“空出来”给 AHK 使用。

有一种典型现象:脚本刚开始有效,过一会儿热键突然全部失效,重启脚本后又能用一会儿。原帖把这类情况称为需要重新挂钩(rehook)。少数游戏会反复重新设置自己的键盘钩子,让自己保持更高优先级。遇到这种情况,可以用定时器反复安装键盘钩子。

放在脚本自动执行段:

SetTimer, Rehook, 500

放在脚本底部:

Rehook:

#InstallKeybdHook

return

原帖作者在后续回复中补充说明:这类情况并不常见,他遇到的典型例子是 South Park: The Stick of Truth。表现是脚本能工作一小段时间,然后突然完全停止;重启脚本又恢复,直到游戏再次重新挂钩。

进阶排查:编译、换用户、远程和虚拟机

如果前面几步都不行,原帖继续列出了一些更进阶的思路。这里按原文如实整理,但读者要明白:越往后,问题越可能不是普通 AHK 语法问题,而是游戏输入模型、安全软件、权限隔离或进程检测问题。

1. 编译成 exe 并改名

把脚本编译成 exe 后,再把程序名改成普通、不显眼的名字。原帖举例:可以改成 setup.exe、skype.exe,或者随机名称。

这一步的核心不是让代码变强,而是改变脚本运行时的进程形态和进程名。是否有效取决于具体游戏。

2. 使用第二个 Windows 用户运行脚本

原帖提到,可以建立第二个用户账户,用另一个用户运行脚本。思路是:游戏和脚本属于不同用户上下文时,某些限制可能无法直接访问另一个用户运行的进程。

这个方法配置成本更高,也更容易引入权限、桌面会话、路径和输入焦点问题,不建议新手作为第一选择。

3. 虚拟机或远程桌面方案

原帖的专家级思路包括:

在虚拟机里运行游戏,在宿主系统外部运行 AHK。

用第二台电脑远程桌面连接游戏电脑,在外部电脑运行 AHK。

这类方案本质是让 AHK 位于游戏进程之外,让游戏不直接看到 AHK,同时仍然让外部系统控制鼠标和键盘。配置成本很高,也不一定适合所有游戏。

4. 模拟 DirectInput

原帖提到,模拟 DirectInput 很困难,AHK 并不原生支持,需要 DLL 交互知识。普通 AHK 脚本一般不要从这里入手。

5. 修改 AutoHotkey 源码中的 mutex 名称

原帖和回复中提到,某些安全软件可能检测 AutoHotkey 默认的 mutex 名称,例如 AHK_KEYBD、AHK_MOUSE。解决方式需要下载 AutoHotkey C++ 源码,修改相关名称后自行编译。

这已经属于自定义解释器层面的处理,不适合普通脚本使用者。除非你明确知道自己在做什么,否则不建议作为常规排查手段。

具体游戏经验整理

以下内容来自原帖和回复整理,主要作为经验参考。不同版本、不同系统和不同设置下结果可能不同。

Final Fantasy XI

通常需要 #UseHook。

Windows 10 用户可能需要让脚本以管理员权限启动,因为游戏也需要管理员权限运行。

League of Legends

按下和松开事件之间建议加 Sleep。

建议使用窗口化模式。

Diablo 3

按下和松开事件之间建议加一个较小 Sleep。

建议使用窗口化模式。

对快速按键的兼容性相对较好。

South Park: The Stick of Truth

可能需要定期重新安装键盘钩子。

游戏可能会覆盖键盘钩子,导致脚本工作一段时间后停止,直到重新加载脚本。

Path of Exile

需要在 MouseMove 和 Click 之间加入延迟。否则可能先在当前位置点击,然后鼠标才移动到目标坐标。

MouseMove, %VarX%, %VarY%

Sleep, 50

Click

原帖记录中暂未解决的游戏

原帖作者记录,当时他所知 AHK 暂未能正常工作的游戏包括:

Wolfenstein: The New Order

这类记录具有时间性。游戏更新、系统更新、AHK 版本、运行权限和窗口模式变化,都可能改变结果。

AHK66 排查建议

如果你只是想让游戏里某个热键、连点、宏按键稳定生效,建议按这个顺序排查:

先用管理员权限运行脚本。

把游戏改成窗口化或无边框窗口化。

把 Send 拆成 down / Sleep / up。

把 Sleep 从 20ms、50ms、100ms 逐步测试。

换一个游戏未占用的热键。

必要时加 #UseHook 或 #InstallKeybdHook。

脚本工作一会儿就失效时,再考虑定时 rehook。

涉及坐标点击时,MouseMove 后加 Sleep 再 Click。

多数“AHK 在游戏里不生效”的问题,通常在前四步就能找到原因。真正需要虚拟机、第二用户、自定义解释器的情况并不多,最好不要一开始就把问题复杂化。

站内延伸

游戏脚本发送按键详解:SendInput 与键盘钩子

为什么 Send 有时失效:SendInput、ControlSend、后台发送的区别

AHK 热键不生效?从权限、输入法、窗口焦点一步步排查

AHK 脚本为什么会误触发:热键穿透、按键连发、修饰键卡住排查

AHK的多键盘-多鼠标支持

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。