AutoHotkey v2 不是简单的“把版本号改一下”。它把很多 v1 时代为了兼容而保留的旧语法清掉了:命令语法、传统赋值、百分号取变量、ErrorLevel、Gui 子命令等都发生了变化。本文按最容易踩坑的顺序整理,适合把旧脚本逐段迁移到 v2 时对照检查。

一、先给脚本写清楚运行版本

迁移前建议在每个脚本开头加上版本声明,避免同一台电脑同时安装 v1/v2 后运行错解释器。

; v1 脚本 #Requires AutoHotkey v1.1

; v2 脚本 #Requires AutoHotkey v2.0

不要一上来就全站式替换。更稳的做法是先挑一个功能完整、依赖较少的小脚本迁移,通过后再处理大型脚本和公共库。

二、命令语法变成函数调用

v1 常见的命令写法在 v2 中基本都变成了函数式写法。最大的变化是:字符串要加引号,变量不再用百分号包起来。

; v1
MsgBox, Hello AHK
Run, notepad.exe
Sleep, 500

; v2
MsgBox "Hello AHK"
Run "notepad.exe"
Sleep 500

如果需要返回值,就用函数返回值;如果只是执行动作,v2 仍然允许省略括号。

三、传统赋值 var = text 要改成表达式赋值

v1 里很多老脚本会写:

; v1
name = AutoHotkey
MsgBox, % name

v2 中应改成:

; v2
name := "AutoHotkey"
MsgBox name

这也是迁移时最常见的第一类报错。经验上,看到单独一行的 =,就要警惕它是不是旧式赋值。

四、百分号取变量大多要删除

v1 命令参数里经常用 %var%% expression 强制表达式。v2 的参数默认就是表达式,所以写法要反过来:变量直接写,普通文本加引号,拼接用空格或函数。

; v1
exe := "notepad.exe"
WinActivate, % "ahk_exe " exe

; v2
exe := "notepad.exe"
WinActivate "ahk_exe " exe

如果字符串比较复杂,建议用 Format(),可读性会比硬拼更好。

; v2
file := "test.txt"
MsgBox Format("当前文件:{}", file)

五、输出变量要用 &,很多命令改成返回值

v1 里不少命令通过参数返回结果:

; v1
MouseGetPos, x, y
WinGetTitle, title, A
PixelGetColor, color, 100, 100, RGB

v2 中要区分两种情况:有些输出变量要加 &,有些命令变成了直接返回。

; v2
MouseGetPos &x, &y
title := WinGetTitle("A")
color := PixelGetColor(100, 100, "RGB")

迁移窗口、图色、文件、注册表、INI 相关代码时,这类改动会非常多,建议一段一段测试。

六、ErrorLevel 不再是主要判断方式

v1 时代很多脚本依赖 ErrorLevel

; v1
ImageSearch, x, y, 0, 0, A_ScreenWidth, A_ScreenHeight, icon.png
if (ErrorLevel = 0)
    Click, %x%, %y%

v2 中优先看函数返回值,并对真正异常的情况使用 try/catch

; v2
if ImageSearch(&x, &y, 0, 0, A_ScreenWidth, A_ScreenHeight, "icon.png")
    Click x, y
else
    MsgBox "没有找到图片"

一些函数在参数错误、文件不存在、窗口不存在等情况下会直接抛异常。迁移时不要简单把所有失败都当成“没找到”,该捕获异常的地方要写清楚。

七、热键多行写法要加大括号

v1 多行热键通常靠 return 结束:

; v1
F1::
MsgBox, 你好
return

v2 推荐写成函数体:

; v2
F1:: {
    MsgBox "你好"
}

还有一个容易忽略的点:v2 的热键函数默认是局部作用域。如果要修改全局变量,需要显式声明。

; v2
count := 0

F1:: {
    global count
    count += 1
    MsgBox count
}

八、#If 要改成 #HotIf

上下文热键迁移时,很多脚本会卡在这里。

; v1
#If WinActive("ahk_exe notepad.exe")
^j::Send, hello
#If

; v2
#HotIf WinActive("ahk_exe notepad.exe")
^j::Send "hello"
#HotIf

九、GUI 从命令式变成对象式

v1 的 GUI 代码通常长这样:

; v1
Gui, Add, Text,, 名字
Gui, Add, Edit, vName
Gui, Add, Button, gSubmit, 确定
Gui, Show
return

Submit:
Gui, Submit
MsgBox, % Name
return

v2 更推荐对象和事件写法:

; v2
myGui := Gui()
myGui.AddText(, "名字")
nameEdit := myGui.AddEdit()
myGui.AddButton(, "确定").OnEvent("Click", (*) => MsgBox(nameEdit.Value))
myGui.Show()

如果旧脚本 GUI 很多,不建议机械替换。先把界面创建、控件变量、按钮事件三部分拆开,再逐步重写。

十、对象字典建议改用 Map

v1 里很多人把普通对象当字典用。v2 中普通对象更偏“属性对象”,任意键值字典建议用 Map

; v2
user := Map()
user["name"] := "AHK"
user["level"] := 2
MsgBox user["name"]

如果旧代码大量使用 obj[key] 存取动态键,迁移时要特别检查它到底应该是对象属性,还是 Map 字典。

推荐迁移顺序

  1. 先加 #Requires,确认脚本由正确版本运行。
  2. 把传统赋值、命令语法、百分号变量改掉。
  3. 处理输出变量、返回值、ErrorLevel。
  4. 再改热键、上下文热键、GUI、对象。
  5. 最后跑一遍真实使用场景,尤其是窗口、图色、剪贴板、文件读写这些容易受环境影响的部分。

结语

v2 的门槛在迁移期会高一些,但迁移完成后,代码会更统一、更容易读,也更适合长期维护。我的建议是:老脚本能稳定运行就不必急着全改;新项目、新教程、新公共库可以优先按 v2 写。

参考资料:AutoHotkey 官方 v1.1 到 v2.0 变更说明

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