常见问题(FAQ)

目录

语言语法

一般故障排查

常见任务

热键, 热字串和重映射

语言语法

什么时候需要在命令和它们的参数中使用引号?

双引号(") 仅在表达式中具有特殊的含义. 在其他的所有地方, 它们像普通字符一样被原义对待. 不过, 当脚本启动程序或文档时, 操作系统通常要求要用引号把含空格的命令行参数括起来, 例如: Run, Notepad.exe "C:\My Documents\Address List.txt".

什么时候需要将变量名括在百分号中?

除了下面用 粗体 表示的情况外, 变量名总是要括在百分号中:

有关百分号如何使用的进一步解释, 请参阅传统语法动态变量. 百分号还可以有其他含义:

什么时候应该对百分号和逗号进行转义?

原义的百分号必须在它们前面加重音符/反引号进行转义. 例如: MsgBox The current percentage is 25`%. 原义的逗号也必须进行转义(`,), 除非在 MsgBox 或任何命令的最后一个参数(在这种情况下可以使用重音符但不是必须的) 使用时.

表达式中的逗号或百分号括在引号中时, 可以使用重音符但是没必要. 例如: Var := "15%".

一般故障排查

如果 AutoHotkey 无法安装, 我该怎么办?

7-zip 错误: 用 7-zip 或其他解压缩软件解压安装程序 EXE, 然后运行 setup.exe 或 Installer.ahk(拖拽 Installer.ahk 到 AutoHotkeyU32.exe 上即可).

AutoHotkey 的安装程序(exe 文件) 以 7-zip 自解压格式打包, 安装时尝试解压文件到用户的临时文件夹并执行编译的脚本进行安装. 有时系统策略或其他原因阻止了文件的解压或执行. 通常在遇到这种情况时会显示 "7-zip 错误" 这样一个消息. 手动解压文件到不同的目录或许能解决该问题.

安装挂死: 如果安装窗口显示空白或不显示, 尝试下面的解决方案:

其他: 以上建议基本能解决遇到的大多数问题. 更进一步的援助, 请到论坛发帖求助.

如何恢复 .ahk 文件的右键菜单选项?

通常情况下, 如果安装了 AutoHotkey, 右键单击 AutoHotkey 脚本文件(.ahk) 应该会提供以下选项:

有时这些选项会被当前用户配置文件中的设置覆盖, 例如是否使用 Open With(打开方式) 更改了打开 .ahk 文件的默认程序. 可以通过删除以下注册表键来解决此问题:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ahk\UserChoice

这可以通过应用此注册表文件来完成.

还可能需要修复默认注册表值, 方法是重新安装 AutoHotkey 或运行 AutoHotkey Setup(从开始菜单) 并在窗口顶部选择 apply(应用).

为什么我脚本中的某些行总是无法执行?

任何想在脚本启动时立即执行的行都应该出现在脚本的顶部, 要在首个热键, 热字串Return 之前. 更多细节请参阅自动执行段.

还有, 含有多行执行语句的热键必须把它的首行写在热键的 下面 而不能在同一行. 例如:

#space::  ; Win+空格键
Run Notepad
; 下面的 "Untitled - Notepad" 为窗口标题, 中文系统应替换为 "无标题 - 记事本". 即
;WinWaitActive 无标题 - 记事本
WinWaitActive Untitled - Notepad
WinMaximize
return

为什么我的脚本在前一个系统运行良好却无法工作于 Windows xxx?

这个问题有许多的影响因素, 例如:

当切换操作系统时, 发生的变动也许影响了你的脚本. 例如, 你的新电脑, 可能有不同的驱动或安装了其他的软件. 如果你升级了新版本的 AutoHotkey, 确认你之前使用的是哪个版本并检查更新记录脚本兼容性.

SoundGet, SoundSet, SoundGetWaveVolumeSoundSetWaveVolume 在 Vista 及之后系统的行为不同于早期版本的 Windows. 尤其是, 设备的设备号是不同的并且某些组件可能不可用. 依赖于音频驱动程序的行为, 必定与在 XP 时是不同的. 这声卡分析脚本能用于找出正确的设备号.

也请参考以下问题:

我该如何处理用户账户控制(UAC) 导致的问题?

在默认情况下, 用户账户控制(UAC) 保护 "提权" 程序(程序以管理员权限运行) 不被非提权程序自动化, 因为这将允许他们绕过安全限制. 热键也将被屏蔽, 因此, 非提权程序不能监视用于提权程序的输入.

UAC 也阻止了 SendPlayBlockInput 的正常工作.

常见的解决方案如下:

我想通过托盘图标编辑脚本, 但它只显示一个错误. 我该怎么办?

首先您必须修复您脚本中的错误才能找回 AHK 的系统托盘图标. 但是您必须先找到您的脚本.

请在下面的文件夹中寻找 AutoHotkey.ahk 文件:

如果您在其他目录中运行 AutoHotkey, 脚本名称取决于 AutoHotkey 可执行文件的名称(不一定是 AutoHotkey.exe). 例如, 如果您运行的是 AutoHotkeyU32.exe, 那么请查找 AutoHotkeyU32.ahk. 注意, 有可能您的系统配置为 ".ahk" 是隐藏文件, 但是文件一定有类似这样的图标 [H]

您可以随时从右键菜单中选择 Edit Script 来编辑 AHK 脚本. 如果这个右键菜单命令无效, 您还可以用记事本或其他文本编辑器来编辑.

如果您是从开始菜单中运行 AutoHotkey 或是直接双击 AutoHotkey.exe 来运行(不包含任何命令行参数), 那么它会查找上述的脚本来执行. 否则, 您可以在任意位置创建一个其他名称的 AHK 脚本文件(something.ahk), 然后运行 AHK 脚本而不是 AutoHotkey.

另请参阅命令行参数 "Script Filename"AutoHotkey.exe 的可移植性.

如何查找代码中的错误并修改呢?

对于简单的脚本, 请参阅调试脚本. 要查看变量的内容, 请使用 MsgBoxToolTip. 对于复杂的脚本, 请参阅交互式调试.

为什么 Run 命令不能启动我的游戏或程序?

有些程序需要在它们自己的目录下运行(不能确定时, 通常最好这样做). 例如:

Run, %A_ProgramFiles%\Some Application\App.exe, %A_ProgramFiles%\Some Application

如果你想要打开的程序位于 %A_WinDir%\System32 并且你是在 64 位系统中使用 32 位的 AutoHotkey, File System Redirector 将会产生干扰. 为避免该问题, 使用 %A_WinDir%\SysNative 代替; 这是一个仅在 64 位系统上运行的 32 位程序可见的虚拟目录.

为什么脚本中的非 ASCII 字符显示或发送不正确?

简短的回答: 将脚本保存为带有 BOM 的 UTF-8.

虽然 AutoHotkey 支持 Unicode 文本, 但它是为了向后兼容而优化的, 这意味着默认为 ANSI 编码, 而不是国际上推荐的 UTF-8. 除非以字节顺序标记(BOM) 开始, 否则 AutoHotkey 不会自动识别 UTF-8 文件.

换句话说, 缺少 BOM 的 UTF-8 文件被错误地解释, 导致非 ASCII 字符被错误地解码. 要解决此问题, 请将文件保存为带有 BOM 的 UTF-8 文件或添加 /CP65001 命令行开关.

要在记事本中保存为带有 BOM 的 UTF-8 文件, 请在另存为对话框的 编码 下拉菜单中选择 带有 BOM 的 UTF-8(或版本早于 Windows 10 v1903 的系统中选择 UTF-8). 请注意, Windows 10 v1903 及以后版本的记事本默认为 UTF-8(没有 BOM)

要读取缺少 BOM 的其他 UTF-8 文件, 请使用 FileEncoding UTF-8-RAW, FileRead*P65001 选项, 或 FileOpen() 的第三个参数 "UTF-8-RAW". -RAW 后缀可以省略, 但是在这种情况下, 任何创建的新文件都会有一个 BOM.

请注意, 使用标准 INI 命令访问 INI 文件不支持 UTF-8; 它们必须保存为 ANSI 或 UTF-16.

为什么热字串, SendClick 在某些游戏中不起作用?

一些游戏禁止 AHK 发送键击和点击或获取像素颜色.

有一些替代方法, 请试试下面提及的方案. 如果这些都无效, 那么 AHK 可能不适用于您的游戏. 一些游戏含有防止反破解和作弊的措施, 如 GameGuard 和 Hackshield. 如果是, 则 AutoHotkey 很可能无法用于该游戏.

如何在玩游戏或平时 CPU 高负荷运行时改善性能?

如果脚本中的热键, 鼠标点击Sends 在 CPU 高负荷运行时明显比正常情况下要慢, 提高脚本程序的优先级或许会有帮助. 要提高脚本进程的优先级, 在脚本开始的部分写入下面这行语句:

Process, Priority, , High

我的杀毒软件把 AutoHotkey 或编译的脚本程序标记为恶意软件. 它真的含有病毒吗?

尽管文件被感染确实是可能的, 但多数情况下这些警报都是 误报, 这意味着防病毒程序是错误的. 一个常见的建议是将文件上传到在线服务, 例如 virustotalJotti 看看其他杀毒软件的查杀结果. 如果有疑问, 您可以将该文件发送给您的杀毒软件供应商确认. 这也可能有助于我们和其他 AutoHotkey 用户, 因为供应商可能会确认这是误报和改善他们的产品与 AutoHotkey 的兼容性.

对于已压缩的编译脚本来说, 误报可能更为常见, 例如使用 UPX(AutoHotkey 1.0 默认, AutoHotkey 1.1 中移除) 或 MPRESS(在AutoHotkey 1.1 中可选). AutoHotkey 安装时不带有压缩程序, 编译脚本时也默认不压缩.

常见任务

我可以在哪里找到官方发行版或更旧的版本?

访问 AutoHotkey 下载页面.

可以在 USB 驱动器中运行 AHK 代码吗?

请参阅 AutoHotkey.exe 的可移植性.

请注意, 当你编译一个使用自动包含函数库的脚本时, AutoHotkey.exe 和 Lib 文件夹必须位于 Ahk2Exe.exe 的上一级目录中(例如 \AutoHotkey.exe 相对 \Compiler\Ahk2Exe.exe). 还需注意 Ahk2Exe 会将设置保存到以下注册表键: HKCU\Software\AutoHotkey\Ahk2Exe. 编译器本身(Ahk2Exe) 不需要运行脚本.

如何获取命令行操作的输出?

测试表明, 由于文件缓存的原因, 对于较少量的输出, 使用临时文件获取会比较快. 事实上, 如果文件在使用后立即被删除, 通常它并没有被真正地写到磁盘上. 例如:

RunWait %ComSpec% /c dir > C:\My Temp File.txt
FileRead, VarToContainContents, C:\My Temp File.txt
FileDelete, C:\My Temp File.txt

要避免使用临时文件(特别是在输出比较大时), 可以考虑使用 Run 命令示例中展示的 Shell.Exec() 方法.

如何让一个脚本关闭, 暂停, 挂起或重启其他的脚本?

首先, 这里有个关闭另一个脚本的例子:

DetectHiddenWindows On  ; 允许脚本隐藏的主窗口能被检测到.
SetTitleMatchMode 2  ; 避免需要指定以下文件的完整路径.
WinClose ScriptFileName.ahk - AutoHotkey  ; 要关闭的脚本的名称(区分大小写).

其次, 要 suspend(挂起), pause(暂停) 或 reload(重启) 另一个脚本, 请把上面脚本的最后一行替换为下列语句中的一行:

PostMessage, 0x0111, 65305,,, ScriptFileName.ahk - AutoHotkey  ; 挂起.
PostMessage, 0x0111, 65306,,, ScriptFileName.ahk - AutoHotkey  ; 暂停.
PostMessage, 0x0111, 65303,,, ScriptFileName.ahk - AutoHotkey  ; 重启.

如何在不退出脚本的情况下停止重复的动作?

通过按下热键来暂停或继续整个脚本, 需要给 Pause 命令指定热键, 例如:

^!p::Pause  ; 按下 Ctrl+Alt+P 暂停脚本. 再次按下以恢复.

要停止在 Loop (循环) 中重复的操作, 请参考下面这个可运行示例, 热键启动和停止自身重复动作. 换句话说, 按下热键将开始循环. 再次按下同样的热键将停止循环.

#MaxThreadsPerHotkey 3
#z::  ; Win+Z 热键(可根据您的喜好改变此热键).
#MaxThreadsPerHotkey 1
if KeepWinZRunning  ;  这说明一个潜在的线程正在下面的循环中运行.
{
    KeepWinZRunning := false  ; 向那个线程的循环发出停止的信号.
    return  ; 结束此线程, 这样才可以让下面的线程恢复并得知上一行所做的更改.
}
; 否则:
KeepWinZRunning := true
Loop
{
    ; 以下四行是您要重复的动作(可根据您的需要修改它们):
    ToolTip, Press Win-Z again to stop this from flashing.
    Sleep 1000
    ToolTip
    Sleep 1000
    ; 但请不要修改下面剩下的内容.
    if not KeepWinZRunning  ; 用户再次按下 Win-Z 来向循环发出停止的信号.
        break  ; 跳出此循环.
}
KeepWinZRunning := false  ; 复位, 为下一次使用热键做准备.
return

如何在任意编辑器中获取上下文相关的 AutoHotkey 命令帮助?

为此 Rajat 创建了这个脚本.

如何检测一个网页何时加载完毕?

对于 Internet Explorer, 可能最可靠的方法是使用 DllCall() 和 COM 正如 www.autohotkey.com/forum/topic19256.html 所演示的. 此外, 获取地址栏及状态栏相关内容的方法在 www.autohotkey.com/forum/topic19255.html 中被提到.

译者注: 适用于旧版程序及使用 COM_L, 可能不适用于新版的程序(需修改相关代码才能适用于新版 AutoHotkey)

旧的, 稳定性稍差的方法: 下面示例中的技术对使用 IE 打开大多数网页时都有效. 类似的方法可能也适用于其他浏览器:

Run, www.yahoo.com
MouseMove, 0, 0  ; 防止状态栏显示鼠标悬停链接而不是 "完成".
WinWait, Yahoo! - 
WinActivate 
StatusBarWait, Done, 30
if ErrorLevel
   MsgBox The wait timed out or the window was closed. 
else 
   MsgBox The page is done loading.

如何比较或操作日期与时间?

EnvAdd 命令能对 YYYYMMDDHH24MISS 格式表示的时间字符串加上或减去一些天数、小时、分钟或秒. 后面的例子从指定的时间中减去 7 天: EnvAdd, VarContainingTimestamp, -7, days.

要计算两个日期或时间之间的时间量, 请参阅 EnvSub, 其中的一个示例. 此外, 内置变量 A_Now 包含了当前本地时间. 最后, 这里有一些内置的日期/时间 变量, 也可以使用 FormatTime 命令来创建自定义格式的日期/时间字符串.

如何发送当前的日期 和/或 时间?

使用 FormatTime内置的日期和时间的变量.

如何发送文本到不活跃或隐藏的窗口?

使用 ControlSend.

如何控制 Winamp, 即使在它未激活时?

请参阅 Winamp 自动化.

如何改变 MsgBox 的按钮名称?

这里有个例子.

如何改变默认编辑器, 即通过上下文菜单或托盘图标打开的那个?

Edit 的示例部分可以找到能让您改变默认编辑器的脚本.

如何保存 GUI 关联变量的内容?

请使用 Gui Submit. 例如:

Gui, Add, Text,, Enter some Text and press Submit:
Gui, Add, Edit, vAssociatedVar
Gui, Add, Button,, Submit
Gui, Show
Return

ButtonSubmit:
Gui, Submit, NoHide
MsgBox, Content of the edit control: %AssociatedVar%
Return

如何用 AHK 画点什么东西?

请参阅 tic 写的 GDI+ standard library. 它可以通过一些基本方法以有限的方式使用 Gui.

如何在窗口出现, 关闭或变成活跃(不) 时执行操作?

使用 WinWait, WinWaitCloseWinWait[Not]Active.

这里列出了用户自己的解决办法, 例如: OnWin.ahk[How to] Hook on to Shell to receive its messages.

热键, 热字串和重映射

如何让我的热键和热字串在 PC 启动时自动生效?

有几种方法可以让脚本(或任何程序) 在每次启动 PC 时自动启动. 最简单的方法是在开始菜单的启动文件夹中放置一个脚本的快捷方式:

  1. 找到脚本文件后选中它, 接着按下 Ctrl+C.
  2. 按下 Win+R 打开运行对话框, 然后输入 shell:startup, 点击确定或按下 Enter. 这将打开当前用户的启动文件夹. 要打开所有用户的启动文件夹, 输入 shell:common startup(不过, 在这种情况下, 您必须以管理员权限进行).
  3. 在文件夹窗口里右击, 点击 "粘贴快捷方式". 脚本的快捷方式现在应该在启动文件夹中了.

我在把鼠标按键作为热键使用时遇到问题. 能提供一些建议吗?

鼠标左键和右键应该可以正常设置为热键(例如, #LButton::Win+LeftButton 热键). 同样地, 鼠标中键和鼠标滚轮的转动应该可以正常地设置为热键, 除非对于驱动直接控制这些按键的鼠标.

第四个按键(XButton1) 和第五个按键(XButton2) 也可以设置为热键, 如果您的鼠标驱动让系统可以看到这些按键的点击时. 如果它们不可见或您的鼠标除了您使用的五个按键外还有更多的按键, 您可以尝试配置鼠标附带的软件(有时需要通过控制面板或开始菜单访问) 来实现当您按下其中的按键时发送键击. 然后可以在脚本中把这样的键击设置为热键. 例如, 如果您配置第四个按键来发送 Ctrl+F1, 然后在脚本中通过使用 ^F1:: 您可以把这个按键间接的设置为热键.

如果您有五键鼠标, 其中的第四和第五个按键不可见, 您可以尝试把鼠标驱动改变为 OS 自带的默认驱动. 这里假设您特殊的鼠标使用自己的驱动并且您不使用鼠标自带软件提供的功能.

如何将 Tab 和空格设置为热键?

使用它们的按键名称(Tab 和 Space) 而不用它们的字符. 例如, #SpaceWin+Space^!TabCtrl+Alt+Tab.

如何将按键或鼠标按键重映射成其他键?

解决的方法在重映射页面说明了.

如何检测按键或鼠标按键的双击?

像下面那样使用可用于热键的内置变量:

~Ctrl::
    if (A_ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 200)
        MsgBox double-press
return

如何让热键热字串只在特定的程序中有效? 换句话说, 在特定的窗口不活动时我想让特定的按键执行它原来的功能.

首选的方法是使用 #IfWinActive. 例如:

#IfWinActive, ahk_class Notepad
^a::MsgBox You pressed Control-A while Notepad is active.

如何让前缀按键执行它原来的功能, 而不是什么都不做?

请参考下面的例子, 其中把 Numpad0 作为前缀键:

Numpad0 & Numpad1::MsgBox, You pressed Numpad1 while holding down Numpad0.

现在, 要让 Numpad0 在没有像上面那样用来触发热键时发送真正的 Numpad0 键击, 需要添加下面的热键:

 $Numpad0::Send, {Numpad0}

使用前缀 $ 是为避免产生关于无效循环的警告对话框(因为此热键 "发送了它自己"). 此外, 上述动作在 释放 此按键的时候发生.

如何改变或禁用 Windows 内置的快捷键, 例如 Win+U(辅助工具管理器) 和 Win+R(运行)?

这里有一些例子.

如何在热字串中使用通配符或正则表达式?

使用 polyethene 写的脚本(含示例).

如何使用不存在于我键盘布局中的热键?

请参阅特殊按键.

我的小键盘上有个特殊的 000 键. 可以把它设成热键吗?

是的. 这个示例脚本000 设成等号键. 您可以用您想要的语句替换 Send, = 来改变动作.