常见问题 (FAQ)

如果您的问题没有在后面列出, 请查看社区维护的 在 AutoHotkey 维基上的 FAQ.

语言语法

常见任务

热键, 热字串和重映射

语言语法

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

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

什么时候需要将变量名装入百分号?

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

1) 在参数中的输入或输出变量: StringLen, OutputVar, InputVar
2) 在赋值表达式的左侧: Var = 123abc
3) 在 传统 (非表达式) if 语句 的左侧: If Var1 < %Var2%
4) 在 表达式 中的任意位置. 例如:

If (Var1 <> Var2)
    Var1 := Var2 + 100

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

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

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

常见任务

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

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

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

#space::  ; Win+空格键
Run Notepad
WinWaitActive Untitled - Notepad
WinMaximize
return

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

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

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

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

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

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

要避免使用临时文件 (特别是对于大量输出时), 可以考虑使用 CmdRetStdoutToVar.

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

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

DetectHiddenWindows On  ; 才可以检测到脚本的隐藏主窗口.
SetTitleMatchMode 2  ; 避免为下面的文件指定完整的路径.
WinClose Script's File Name.ahk - AutoHotkey  ; 根据脚本的名称 (区分大小写) 更新此语句.

挂起暂停 另一个脚本, 请把上面脚本的最后一行替换为下列语句中的一个:

PostMessage, 0x111, 65305,,, Script's File Name.ahk - AutoHotkey  ; 挂起.
PostMessage, 0x111, 65306,,, Script's File Name.ahk - AutoHotkey  ; 暂停.

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

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

^!p::Pause  ; 按 Ctrl+Alt+P 暂停. 再按一次则恢复.

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

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

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

当 CPU 高负荷运行时, 如果脚本里的 热键, 点击发送 明显比平时慢, 那么提高脚本的进程优先级可能会有所帮助. 要做到这点, 请在脚本的顶部附近包含下面这行语句:
Process, Priority, , High

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

为此 Rajat 创建了 此脚本.

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

对于 Internet Explorer, 可能最可靠的方法是使用 DllCall 和 COM, 正如 www.autohotkey.com/forum/topic19256.html 所演示的. 相关提示, 通过 www.autohotkey.com/forum/topic19255.html 演示的方法可以获取地址栏和状态栏的内容.

旧的, 较不可靠的方法: 下面示例中的技术对使用 MS Internet Explorer 打开大部分页面时都有效. 类似的技术对于其他的浏览器可能也有效:

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 命令.

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

有些游戏独占方式来使用 DirectInput. 副作用是它们可能会忽略所有模拟的键击和鼠标点击. 要避免此问题, 请尝试下列方法之一 (或组合使用):

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

请参阅 让 Winamp 自动化.

如何改变 MsgBox 的按钮名称?

这里有个 例子.

热键, 热字串和重映射

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

在开始菜单中有个名称为启动的文件夹, 如果您把脚本的快捷方式放入此文件夹, 那么脚本会在您每次启动 PC 时自动运行. 要创建快捷方式的话:

  1. 找到脚本文件后选中它, 接着按下 Control-C.
  2. 右键点击开始按钮 (通常在屏幕的左下角) 并选择 "浏览所有用户".
  3. 定位到程序文件夹中的启动文件夹.
  4. 在菜单栏选择 编辑 -> 粘贴快捷方式.  脚本的快捷方式现在应该出现在启动文件夹中了.

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

请注意当前 鼠标热键 在 Windows 95/98/Me 中是不可用的. 在其他操作系统上, 鼠标左键和右键应该可以正常地设置为热键 (例如, #LButton:: 为 Win+LeftButton 热键). 同样地, 鼠标中键和 鼠标滚轮 的转动应该可以正常地设置为热键, 除非对于驱动直接控制这些按钮的鼠标.

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

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

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

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

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

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

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

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

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

Windows 95/98/Me: 尽管上述方法有效, 但在记事本以外的窗口按下 Control-A 将没有任何效果 (甚至没有它原有的功能). 要避免此问题, 请使用:

$^a::Send ^a  ; 在 Windows 9x 上, 此热键必须 首先 列出. $ 前缀让热键能 "发送它自己".
#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 (运行)?

这里有一些 例子.

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

可以, 不过仅当你使用 Windows NT, 2000, XP 或以上版本时才行. 这个 示例脚本 把 000 键设成等号键. 您可以用您想要的语句替换 "Send, =" 来改变动作.