OnExit
指定一个在脚本退出时自动运行的 子程序 (通常表示标签) 或 函数.
OnExit [, Label]
OnExit(Func [, AddRemove]) ; 需要 [v1.1.20+]
参数
- Label
如果省略, 则脚本会返回到正常的退出行为. 否则, 请指定 label (标签) 的名称, 当脚本由于任意原因退出时将执行标签中的内容 (作为新 线程).
- Func
脚本退出时调用的一个函数名称或 函数对象 . 该函数还可以有选择的定义参数, 请参考下面的例子. 如果 OnExit 调用的函数返回一个非零整数, 脚本将不会继续退出. 否则, 脚本将在该函数运行完成之后退出.
ExitFunc(ExitReason, ExitCode)
- AddRemove
下列的某个值:
1: (默认) 在所有之前注册的函数之后调用该函数.
-1: 在所有之前注册的函数之前调用该函数.
0 : 不调用该函数.总是优先调用注册的 label (标签) (子程序).
Remarks
注意: 这是调用子程序而不是退出脚本, 如果希望最终能退出脚本, 该子程序必须使用 ExitApp 命令. [v1.1.20+]: 推荐新脚本使用函数替代原来的标签 (子程序) 形式 -- 这样可以降低脚本无法退出的风险, 还能确保传递给 Exit 或 ExitApp 的退出码是可控的(保存).
[v1.1.20+]: OnExit 函数可以注册任意多个. 如果同时还注册了 label (子程序) 也会被注册, 注册的这些函数会在子程序执行 ExitApp 命令之后被调用. 通常 OnExit 不需要调用 ExitApp 命令; 如果调用了, 脚本将会立即退出.
OnExit 子程序在(收到)任何 means (译者注:理解为有意的退出信息) 时被调用 (除非被类似 "结束任务" 的方式强行终止). 无论脚本之前的实例是否使用了 #SingleInstance 和 Reload 命令都可调用它来终止脚本.
脚本可以检测甚至终止操作系统关闭或注销, 用这段代码即可 OnMessage(0x11, "WM_QUERYENDSESSION")
.
OnExit 线程 并不受到 #MaxThreads 的限制 (它总是在需要的时候启动). 此外, 当它运行时, 它不会被任何 线程 中断, 包括 热键, 自定义菜单项, 和 定时器子程序 . 不过, 它会在这些情况下被终止 (且脚本也同时被终止了) : 用户从系统栏 或 主菜单栏中选择 exit 退出, 或脚本被 Reload 或 #SingleInstance 请求作为返回值. 由于这些原因, OnExit 子程序应该被设计为尽快结束, 除非用户知道自己在做什么.
如果 OnExit 线程 遇到失败条件, 比如运行时错误时, 脚本将会终止. 这可以防止有缺陷的 OnExit 子程序脚本无法终止.
如果 OnExit 子程序由 Exit 或 ExitApp 启动并设置了退出码, 在 v1.1.19 和之前的版本中被将忽略且不可获取. 而从 [v1.1.20+] 开始, 最初的退出码将使用, 除非使用 ExitApp 指定了新的退出码.
任何当 OnExit 子程序被 exit 尝试调用时, 它都会使用脚本默认配置, 如 SendMode. 这些默认配置可在 auto-execute section (自动运行区域) 改变.
内置变量 A_ExitReason 为空,除非 OnExit 子程序正在运行或者在之前的退出中至少调用过一次.如果不是空的, 则它为下列单词的其中一个:
logoff | 用户正在注销. |
Shutdown | 正在关闭或重启系统, 例如使用 Shutdown 命令. |
Close | 脚本接收到 WM_CLOSE 或 WM_QUIT 消息, 出现致命错误或者正被以其他方式关闭. 尽管这些情况都是很少见的, 然而 WM_CLOSE 可能是由脚本主窗口使用 WinClose 命令发出的. 要避免这种情况,请使用 Send, !{F4} 关闭主窗口. |
错误 | 在没有热键且不是 持续运行的 脚本中发生了运行时错误. 运行时错误的一个例子是 Run/RunWait 命令无法启动指定的程序或打开指定的文档. |
Menu | 用户在主窗口的菜单或标准托盘菜单中选择了退出. |
Exit | 使用了 Exit 或 ExitApp 命令 (包括 自定义菜单项). |
Reload | 正通过 Reload 命令或菜单项重载脚本. |
Single | 由于 #SingleInstance 的结果, 脚本正被它自身的新实例代替. |
相关
OnMessage(), RegisterCallback(), OnClipboardChange, ExitApp, Shutdown, #Persistent, Threads, Gosub, Return, Menu
示例
下面的例子使用 #Persistent 来防止脚本自动退出. 脚本启动之后, 在系统栏图标上点击鼠标右键选择 Exit 来测试 OnExit 子程序或函数. 然后点击 "Yes" 来终止脚本 或 "No" 使脚本继续运行.
#Persistent OnExit, ExitSub return ExitSub: if A_ExitReason not in Logoff,Shutdown ; 在这行语句中, 注意不要在逗号周围含有空格. { MsgBox, 4, , Are you sure you want to exit? IfMsgBox, No return } ExitApp ; 脚本含有 OnExit 子程序时不会立即终止, 除非子程序使用 ExitApp.
#Persistent ; 注册一个在退出时调用的函数: OnExit("ExitFunc") ; 注册一个在退出时调用的对象: OnExit(ObjBindMethod(MyObject, "Exiting")) ExitFunc(ExitReason, ExitCode) { if ExitReason not in Logoff,Shutdown { MsgBox, 4, , Are you sure you want to exit? IfMsgBox, No return 1 ; OnExit 函数必须返回非零值来防止退出. } ; 不要用 ExitApp -- 那会阻止其他 OnExit 函数被调用. } class MyObject { Exiting() { MsgBox, MyObject is cleaning up prior to exiting... /* this.SayGoodbye() this.CloseNetworkConnections() */ } }