常见问题(FAQ)

目录

一般故障排查

常见任务

热键, 热字串和重映射

一般故障排查

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

如果无法正常安装 AutoHotkey, 请参阅如何安装 AutoHotkey 获取更多帮助.

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

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

注意: 在 Windows 11 上, 其中一些选项通常被归入一个子菜单, 可以通过选择 "显示更多选项" 来访问.

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

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

这可以通过应用此注册表文件, 或通过运行 AutoHotkey 安装目录中的 UX\reset-assoc.ahk 来完成.

它可能需要修复默认的注册表值, 通过重新安装 AutoHotkey 或运行 AutoHotkey 安装目录中的 UX\install.ahk 来完成.

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

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

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

也请参考以下问题:

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

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

UAC 也阻止了 SendPlay 和 BlockInput 的正常工作.

常见的解决方案如下:

因为脚本出错而无法启动, 我不能通过托盘图标编辑我的脚本. 我该怎么办?

首先您必须修复您脚本中的错误才能找回 AHK 的系统托盘图标. 这将需要找到脚本, 并在编辑器中通过托盘图标以外的其他方式打开它.

如果您直接运行 AutoHotkey 的可执行文件, 则脚本的名称取决于可执行文件. 例如, 如果您正在运行 AutoHotkey32.exe, 请在同一目录下查找 AutoHotkey32.ahk. 请注意, 根据您的系统设置, ".ahk" 部分可能被隐藏, 但文件应该有一个像 [H] 的图标.

您通常可以通过右键单击脚本文件并选择 Edit Script 来编辑脚本文件. 如果这不起作用, 您可以在记事本或其他编辑器中打开该文件.

通常, 您应该在任何您喜欢的地方创建脚本文件(something.ahk), 并运行该脚本文件, 而不是直接运行 AutoHotkey.

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

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

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

为什么 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 字符显示或发送不正确?

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

非 ASCII 字符由不同的二进制值来表示, 这取决于所选择的编码. 为了让这些字符被正确的解释, 您的文本编辑器和 AutoHotkey 必须在 同一个代码页. AutoHotkey v2 默认所有的脚本文件都是 UTF-8, 尽管可以通过 /CP 命令行开关来重写.

要在记事本中保存为 UTF-8 文件, 请在另存为对话框的 编码 下拉菜单中选择 UTF-8 或 带有 BOM 的 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.

为什么 Hotstrings, Send 和 Click 在某些游戏中不起作用?

不是所有的游戏都支持 AHK 发送键击和点击或获取像素颜色.

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

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

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

ProcessSetPriority "High"

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

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

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

常见任务

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

访问 AutoHotkey 下载页面.

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

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

如何检索命令行操作的输出?

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

RunWait A_ComSpec ' /c dir > C:\My Temp File.txt'
VarToContainContents := FileRead("C:\My Temp File.txt")
FileDelete "C:\My Temp File.txt"

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

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

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

DetectHiddenWindows True  ; 许脚本隐藏的主窗口能被检测到.
SetTitleMatchMode 2  ; 避免需要指定以下文件的完整路径.
WinClose "ScriptFileName.ahk - AutoHotkey"  ; 更新它为脚本的实际名称(区分大小写).

其次 suspend 或 pause 另一个脚本, 请把上面脚本的最后一行替换为下列语句中的一行:

PostMessage 0x0111, 65305,,, "ScriptFileName.ahk - AutoHotkey"  ; Suspend(挂起).
PostMessage 0x0111, 65306,,, "ScriptFileName.ahk - AutoHotkey"  ; Pause(暂停).
PostMessage 0x0111, 65303,,, "ScriptFileName.ahk - AutoHotkey"  ; Reload(重载).

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

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

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

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

#MaxThreadsPerHotkey 3
#z::  ; Win+Z 热键(可根据您的喜好改变此热键).
{
    static KeepWinZRunning := false
    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  ; 复位, 为下一次使用热键做准备.
}
#MaxThreadsPerHotkey 1

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

为此 Rajat 创建了这个脚本.

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

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

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

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

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

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

Result := DateAdd(VarContainingTimestamp, -7, "days")

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

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

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

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

请使用 ControlSend.

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

请参阅自动化 Winamp.

如何改变 MsgBox 的按钮名称?

这里有个例子.

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

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

如何保存我的 GUI 控件的内容?

请使用 Gui.Submit. 例如:

MyGui := Gui()
MyGui.Add("Text",, "Enter some Text and press Submit:")
MyGui.Add("Edit", "vMyEdit")
MyGui.Add("Button",, "Submit").OnEvent("Click", Submit)
MyGui.Show()

Submit(*)
{
    Saved := MyGui.Submit(false)
    MsgBox "Content of the edit control: " Saved.MyEdit
}

我能使用 AHK 画点什么吗?

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

如何在窗口出现, 关闭或变成[不]活跃时开始一个动作?

使用 WinWait, WinWaitClose 或 WinWait[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+左键). 同样地, 鼠标中键和鼠标滚轮的转动应该可以正常地设置为热键, 除非鼠标驱动直接控制这些按键.

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

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

如何将 tab 和空格键定义为热键?

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

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

这在重映射页面进行了描述.

如何检测按键或按钮的双击?

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

~Ctrl::
{
    if (ThisHotkey = A_PriorHotkey && A_TimeSincePriorHotkey < 200)
        MsgBox "double-press"
}

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

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

#HotIf WinActive("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 键. 可以把它设成热键吗?

You can. 这个示例脚本将 000 键设成等号键. 你可以通过使用你的代码替换 Send "=" 这行来更改这个动作.