来源出处:本文中文移植自 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 排查建议

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

  1. 先用管理员权限运行脚本。
  2. 把游戏改成窗口化或无边框窗口化。
  3. 把 Send 拆成 down / Sleep / up。
  4. 把 Sleep 从 20ms、50ms、100ms 逐步测试。
  5. 换一个游戏未占用的热键。
  6. 必要时加 #UseHook#InstallKeybdHook
  7. 脚本工作一会儿就失效时,再考虑定时 rehook。
  8. 涉及坐标点击时,MouseMove 后加 Sleep 再 Click。

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

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