OnExit 可以用作函数或命令, 但建议在新脚本中使用前者. 作为一个函数, 它注册一个 函数, 以便在脚本退出时自动调用. 作为一个命令, 它注册一个 子程序, 以便在脚本退出时自动调用.
注册一个在脚本退出时自动调用的函数.
OnExit(Callback , AddRemove)
要调用的函数或函数对象的名称. 若要传递原义的函数名称, 将其括在双引号中.
回调函数接受两个参数, 可以定义如下:
MyCallback(ExitReason, ExitCode) { ...
虽然你给参数的名称并不重要, 但是下面的值会依次赋值给它们:
如果不需要相应的信息, 可以从回调函数的参数列表末尾省略一个或多个参数.
回调可以返回一个非零的整数来阻止脚本退出(除了一些罕见的例外), 也不会再调用其他回调. 否则, 脚本将在调用所有注册回调之后退出.
如果省略, 则默认为 1. 否则, 指定下列数字之一:
如果下面的 OnExit 命令已经注册了子程序, 则总是首先调用该子程序.
可以注册任意数量的回调. 如果还注册了子程序(通过下面的 OnExit 命令), 则在子程序调用 ExitApp 之后调用回调. 回调通常不应该调用 ExitApp; 如果调用了, 则脚本立即终止.
注册要在脚本退出时自动调用的子程序.
过时的: 不推荐在新脚本中使用此命令. 使用上面描述的 OnExit() 函数来减少意外创建无法退出的脚本的风险,并确保传递给 Exit 或 ExitApp 的退出码被保存.
OnExit , Label
由于注册的子程序被调用而不是退出脚本, 因此如果需要退出脚本, 子程序中必须使用 ExitApp. (译者注: 每次遇到退出, 就执行子程序, 相当于退出命令被子程序取代了而不会被执行, 不过在子程序运行时(完成之前), 再次选择退出时, 不会再次调用子程序, 而是退出, 详情请参阅下面的备注.)
内置变量 A_ExitReason 为空, 除非注册的子程序正在运行或者在之前的退出中至少调用过一次. 如果不是空的, 则它为下面表格中单词的其中一个.
当脚本以任何方式退出时, 将调用回调或子程序(除非被类似 "结束任务" 的方式强行终止). 每当 #SingleInstance 和 Reload 请求前一个实例终止时, 也会调用它.
脚本可以通过 OnMessage(0x0011, "WM_QUERYENDSESSION")
(有关工作脚本, 请参阅 OnMessage 示例 #2) 检测并可选择地中止操作系统关闭或注销.
OnExit 线程并不受到 #MaxThreads 的限制(它总是在需要的时候启动). 此外, 当它运行时, 它不会被任何线程中断, 包括热键, 自定义菜单项和计时器子程序. 不过, 它会在这些情况下被中断(终止)(且脚本也同时被终止了): 用户从托盘菜单或主菜单栏中选择 exit(退出), 或由于 Reload 或 #SingleInstance 而要求脚本终止. 由于这些原因, 回调或子程序应该被设计为尽快结束, 除非用户知道它在做什么.
如果 OnExit 线程遇到失败条件, 比如运行时错误时, 脚本将会终止. 这可以防止有缺陷的回调或子程序使脚本无法终止.
如果 OnExit 线程由 Exit 或 ExitApp 启动并指定了退出码, 在 [v1.1.19] 和之前的版本中将被忽略, 且不再可用. 而从 [v1.1.20+] 开始, 除非使用 ExitApp 指定了新的退出码, 否则将使用最初的退出码.
每当进行一个退出尝试时, 每个回调或子程序都将以 SendMode 等设置的默认值启动. 这些默认值可以在自动执行段中更改.
原因 | 描述 |
---|---|
logoff | 用户正在注销. |
Shutdown | 正在关闭或重启系统, 例如使用 Shutdown 命令. |
Close |
脚本发送 WM_CLOSE 或 WM_QUIT 消息, 出现致命错误, 或者正在被其他方式关闭. 尽管这些情况都是很少见的, 然而 WM_CLOSE 可能是由于在脚本主窗口使用 WinClose 命令而引起的. 要关闭(隐藏) 窗口而不终止脚本, 请使用 WinHide. 如果脚本因严重错误或其主窗口被被销毁而退出, 它将在 OnExit 线程完成后无条件终止. 如果主窗口正在被销毁, 它可能仍然存在, 但不能显示. 这个条件可以通过使用 OnMessage() 监听 WM_DESTROY 消息来检测. |
Error | 在没有热键且不是持续运行的脚本中发生了运行时错误. 运行时错误的一个例子是 Run/RunWait 命令无法启动指定的程序或打开指定的文档. |
Menu | 用户在主窗口的菜单或标准托盘菜单中选择了退出. |
Exit | 使用了 Exit 或 ExitApp(包括自定义菜单项). |
Reload | 正通过 Reload 命令或菜单项重载脚本. |
Single | 由于 #SingleInstance 的结果, 脚本正被它自身的新实例代替. |
OnError(), OnMessage(), RegisterCallback(), OnClipboardChange, ExitApp, Shutdown, #Persistent, Threads, Gosub, Return, Menu
尽管语法不同, 但这两个例子都有相同的效果; 即它们在退出脚本之前询问用户. 要测试它们, 右击托盘图标然后单击 Exit(退出).
#Persistent ; 防止脚本自动退出. OnExit("ExitFunc") ExitFunc(ExitReason, ExitCode) { if ExitReason not in Logoff,Shutdown ; 避免逗号周围的空格. { MsgBox, 4, , Are you sure you want to exit? IfMsgBox, No return 1 ; 回调必须返回非零值来避免退出. } ; 不要调用 ExitApp -- 那会阻止其他回调被调用. }
#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 ; 脚本含有注册的子程序时不会终止, 除非子程序使用 ExitApp.
#Persistent ; 防止脚本自动退出. OnExit(ObjBindMethod(MyObject, "Exiting")) class MyObject { Exiting() { MsgBox, MyObject is cleaning up prior to exiting... /* this.SayGoodbye() this.CloseNetworkConnections() */ } }