H 版很适合把脚本做成正式工具,但发布前要补的东西,不只是“编译成 exe”。一个给别人用的工具,至少要考虑版本信息、窗口类名、资源文件、退出清理、异常日志和位数兼容。
这篇我按发布前检查清单来写。不是每个脚本都要全部用上,但只要准备发给别人长期使用,就值得逐条看一遍。
先固定脚本入口【基础规范】
发布工具最怕入口混乱。自动执行段、热键、GUI、初始化、退出逻辑最好分清楚。脚本开头可以保持简洁稳定。
#Requires AutoHotkey v1.1 #NoEnv #SingleInstance Force SetBatchLines, -1 SetWorkingDir, %A_ScriptDir% AppName := "MyTool" AppVersion := "1.0.0" OnExit, AppExit Gui, Add, Text,, %AppName% %AppVersion% Gui, Show, w300 h120, %AppName% return GuiClose: AppExit: ExitApp
版本号建议从一开始就写。以后用户反馈问题时,“你用的是哪个版本”比“你下载的是哪个文件”清楚得多。
窗口类名要清楚
H 版可以用 #WindowClassMain 和 #WindowClassGui 修改默认窗口类名。发布工具时,我建议使用自己的工具名,不要假装系统窗口,也不要和别的软件撞名。
#WindowClassMain Ahk66ToolMain #WindowClassGui Ahk66ToolGui Gui, Add, Text,, 用 AHKInfo 可以看到这个 GUI 的类名 Gui, Show, w320 h100, H 版窗口类名测试 return GuiClose: ExitApp
类名固定以后,后续用 AHKInfo、WinExist、ahk_class 排查问题会方便很多。多工具共存时,也不容易互相误伤。
补完整 exe 信息
很多脚本编译后还是默认图标、默认说明、默认版本。自己用问题不大,发给用户就显得粗糙。Ahk2Exe 支持在脚本里写编译指令,把图标、产品名、文件版本一起带进去。
CurrentToolVersion := "1.2.0" ;@Ahk2Exe-SetMainIcon Icon\tool.ico ;@Ahk2Exe-ExeName %A_ScriptDir%\Build\MyTool.exe ;@Ahk2Exe-SetCompanyName AHK66 ;@Ahk2Exe-SetCopyright AHK66 ;@Ahk2Exe-SetDescription 我的 H 版工具 ;@Ahk2Exe-SetFileVersion 1.2.0 ;@Ahk2Exe-SetProductVersion 1.2.0 ;@Ahk2Exe-SetProductName 我的 H 版工具
这些信息看似不起眼,但用户在文件属性、任务管理器、杀软提示、问题反馈里都会看到。正式工具不要省。
资源文件怎么处理
发布时常见资源包括图标、配置模板、DLL、图片、音效、字库、模型文件等。简单资源可以用 FileInstall;更高级的场景可以研究 H 版的资源提取、Zip 打包和内存加载。
resDir := A_AppData "\AHK66\MyTool"
FileCreateDir, %resDir%
FileInstall, assets\default.ini, %resDir%\default.ini, 1
if !FileExist(resDir "\default.ini")
{
MsgBox, 资源释放失败
ExitApp
}
资源释放路径不要随便放当前目录。用户可能把 exe 放在桌面、下载目录、只读目录、同步盘里。配置和运行数据更适合放到用户目录或 AppData。
线程和 COM 要正常退出
如果工具用了 H 版线程,不要把关闭按钮写成简单 ExitApp 就完事。子线程、COM 对象、文件句柄、临时窗口都要有退出路径。
state := CriticalObject()
state.stop := false
worker := AhkThread(A_ScriptDir "\worker.ahk", "" (&state), true)
AppExit:
state.stop := true
Sleep, 500
if IsObject(worker)
worker.ahkTerminate()
ExitApp
强制结束线程只能兜底。线程里如果创建了 Excel、Outlook 这类 COM 对象,要尽量在线程内部主动 Quit、释放引用,再退出。
日志要能定位问题
正式工具不一定要弹一堆技术错误给用户,但至少要留下日志。日志里优先记录时间、版本、脚本路径、错误信息、用户正在做什么。
Log(msg)
{
global AppName, AppVersion
logDir := A_AppData "\AHK66\" AppName
FileCreateDir, %logDir%
FileAppend, %A_Now% [%AppVersion%] %msg%`n, %logDir%\run.log, UTF-8
}
能让用户把日志发回来,后面维护会轻松很多。尤其是窗口权限、路径权限、杀软拦截、网络接口失败这些问题,只靠一句“不能用”很难判断。
位数和依赖要写清楚
H 版发布时要特别注意 32 位和 64 位。外部 DLL、COM、驱动、窗口句柄、内存地址相关代码,都可能受位数影响。
- 调用 32 位 DLL,就用 32 位程序。
- 调用 64 位 DLL,就用 64 位程序。
- 需要访问其他程序内存时,优先保持位数一致。
- 如果版本依赖 VC 运行库,要把依赖说明清楚,或者选不依赖额外运行库的版本。
发布前最后看一遍
- 脚本是否能在干净目录运行。
- 配置文件不存在时是否会自动创建。
- 资源释放失败时有没有提示。
- 窗口类名、标题、托盘菜单是否清楚。
- 退出时线程、COM、临时文件是否清理。
- exe 文件名、图标、版本信息是否完整。
- 32 位和 64 位是否按实际依赖测试过。
H 版打包发布的核心不是把脚本藏起来,而是把工具做稳。脚本自己用可以随意一点,发给别人用就要把入口、资源、日志、退出和版本这些细节补齐。
H 版帮助文档
- AHK_H v1 帮助文档总览:查看 H 版新增命令、函数和 DLL 说明。
- #WindowClassMain:编译后修改主窗口类名。
- #WindowClassGui:编译后修改 GUI 窗口类名。
- ResPutFile:把文件写入资源。
- ResPut:写入资源数据。
- CryptAES:AES 加密解密相关函数。
- Zip Functions:Zip 打包、解包、内存压缩相关函数入口。
- AhkThread:H 版多线程入口,创建新的 AHK 执行环境。
- CriticalObject:线程之间共享对象时最常用的安全包装。
站内相关链接
- AHK_H 资源提取和 Zip 打包示例:资源内置、释放和打包时可以继续看。
- AHK_H 字符串和文件加密压缩示例:需要做简单保护或压缩处理时参考。
- AHK_H 报错处理:错误捕获、日志保存和异常提示:发布工具前,最好先把日志和异常提示补上。
- AHK_H 运行时追加代码:addScript 的即时扩展用法:适合需要动态加载或扩展脚本能力的场景。
- 调用 AutoHotkey.dll 的用法示例:如果发布方案涉及 DLL 嵌入,可以先看这一篇。
- AHKv1_H 版到底怎么学:回到 H 版整体学习路线。

评论(0)