有必要迁移到 AutoHotkey V2 吗?

现在用着 AutoHotkey v1.1,遇到的情况就是有时脚本会无故退出(还好比 Listary 3自退频率低),现在遇到过就两个脚本有这种情况,而且是最近才遇到的,出现次数较多的是热键脚本,另一个出现一次的是有定时检测的脚本。我只用火绒,但火绒日志也没相关记录,脚本代码也是已经长久没变动的。
所以,

  1. AutoHotkey V2 的运行稳定性如何?
  2. 自动转换V2的程序能百分百转换成功吗?V1脚本转V2有什么要注意的点啊?
  3. 有没有调试AHK的集成工具,例如可以逐步运行和同步显示变量值而不需要在代码添加语句的?

我是因为不喜欢 v1 的语法才转的,然后呢我写的都是很小的脚本,因此转换比较顺利。如果你没有什么很大型的脚本话,或许我的经验能给你一些帮助。

  1. 运行稳定性,这个我不确定,无论是 v1.1 抑或是 v2 我都没遇到过你所提及的无故退出的问题,所以我无法给出参考。
    • 自动转换,你是指 AHK-v2-script-converter 吗?这个我试过一点,但最终还是不放心它的质量(即使转换还有很多地方仍是手动修改)。我感觉应该不算成熟,如果代码量不大的话(我转 v2 增删代码规模不到 2k,代码量不算大,因此也就能接受手动转换的工作量),还是亲自手动转换吧,顺便熟悉 v2 语法。
    • 要注意的点嘛,我写过一篇记录「AutoHotkey 脚本重构小记」,由于我也只是个 AutoHotkey 新手,因此触及的点比较浅薄,也比较啰嗦,想看也可以看看,也许能有参考。当然归根结底还是要常翻阅文档,可以 v1 v2 对比看。
  2. 建议使用 VSCode,然后搭配插件 AutoHotkey v2 Language SupportAutoHotkey Plus Plus,你所需的功能就能实现了。

想过迁移,想了10秒钟就放弃了,代价太大了。用了10年的ahk,一大堆自己的库,别人的库,各种嵌套互相调用。以前都是拿来就用的,现在要迁移修改,那不得自己重新阅读理解啊,关键大神的库我都看不懂。想想头都要炸。有这精力不如重新学一门语言了。我就永远停留在1.1.37.01了吧。有点伤感。

你需要面对的是,当你说的大神都转向了 V2,你停留的不仅是版本,还有你的脚本。
学习新语言和用这个新语言写出当前脚本,不是一回事。V2 本身并不复杂。
我的经验是,V1 脚本可以不转换,但新脚本,一定要用 V2 实现。没过几个月,我熟悉 V2 后,就完全转换成 V2 了,虽然用了几个月。

v2比v1强在哪里啊?

自 v1.1 来的更改 | AutoHotkey v2 还改了挺多

有没有方法让1.1和2同时运行,手动指定每个ahk运行的版本

可以同时安装 v1.1 和 v2,我就同时装了 v1.1.37.01 和 v2.0.11,参阅官方文档:与 v1 同时安装

至于为每个脚本指定版本,你可以打开 <安装路径>/AutoHotkey/UX/ui-launcherconfig.ahk 进行配置,可以选择自动检测版本,并指定检测失败时操作。同时还可以使用 #Requires

我现在用v2

我有个用 v1 写的每天高频使用的自用脚本,从去年2月开始试图用 V2 改写,有两个调用的库找不到替代,自己试图重写奈何太小白,chatGPT 又太白痴v2混着v1瞎给建议。后来,居然在 reddit 找到了v2版,成功把脚本改成v2了。所以说,网上这些大神什么都有,想改v2还是挺有希望的。

后来想了想,我大概是有强迫症,看着 v1 v2 混用就不爽。

想问一下各位,AutoHotkey V2 能实现以下这样的函数吗?

function 加Shift(按键){
if (Shift键按下)
sendinput +{按键}
else
sendinput {按键}
}

这样使用:
space & f:: 加Shift(‘Left’)

能跑就不要动它
认真问下,迁移到v2有啥好处?

参考官方文档 GetKeyState 函数。

获取Shift键状态我会,问题是我能否传一个键名变量来让sendinput发送该键的键击?


算了,会用V1写了:

isShift(thekey) {
    If (GetKeyState("Shift"))
        sendinput, +{%thekey%}
    Else
        sendinput, {%thekey%}
}
key := "F"
!a::SendInput("+{" key "}")

这种?还可以写成

key := "F"
!a::SendInput(Format("+{{}{1}{}}", key))

参见 Format 文档。另外建议阅读 AutoHotkey 初学者向导

原本这部分没问题的,但问题在于另一个匹配检测的语句,想将其写成遍历数组避免重复多行,结果死活遍历不了数组又不抛出错误(就是遍历内的语句不执行,完全不执行),只好换了V2来重写整个快捷键脚本。
现在遇到一个问题:
V1 中 #if 包裹一堆快捷键的话,这些快捷键在触发的时候会先检查 #if 的条件;现在V2取消了这种写法,是必须这堆快捷键都添加个if,还是有什么简略方法?

不清楚具体状况,不过我想到两种方法:

其实重写时可以看看自 v1.1 来的更改 | AutoHotkey v2 (wyagd001.github.io),你搜一下「#If」就会发现重命名为「#HotIf」了,其它也是类似的。

我就是在那里的“搜索”功能里搜“if”没有找到…… :man_facepalming:
p.s. vscode的ahk插件直接把我文件名末尾是“V2”的ahk文件视作V2格式的……不得不说很合理 :joy:


剩下就是为什么V1的数组遍历不执行的问题了,问题代码:

SetWorkingDir %A_ScriptDir%
#UseHook On

Menu, Tray, Icon, ##空格键快捷键.ico
Process, Priority,, High
; ↓↓这行在V1中不能折行写还是折行了不能注释,反正折行会提示非法字符
imepanels := ["VNDDSKIN_CAND","ATL:00007FFD2C972A50","ATL:0F88E8B8","yong_input","SOUIHOST"]  ;多多 ;rime ;rime ;小小 ;启程
n := imepanels.Length()
; ↓↓此处可以正常输出调试信息
OutputDebug, start %n%
;躲避输入法候选提示,避免空格上屏时触发脚本响应而导致误输入
isImeOff() {
    r := true
    ; ↓↓此两句也能正常输出调试信息
    OutputDebug, sta %r%
    OutputDebug, % n
    For ind, val in imepanels 
    {
        ; ★ 从这开始的调试信息就【没出现过】,AHK自己的执行日志中也没有
        OutputDebug, % val
        WinGetPos, x, , , , ahk_class %val%
        OutputDebug, % ind x
        r := r && (x = "") ;x为空表明输入法候选未显示在屏幕上
        OutputDebug, % ind r
    }
    ; ↓↓直接就跳到这里输出调试信息了
    OutputDebug, final %r%
    Return r
}

因为rime的候选提示窗口是一直存在的,所以才使用窗口位置来进行判断

请问有什么高明的v1转v2工具?