# OnExit

指定一个 子程序 在脚本退出时自动运行.

OnExit [, Label]

#### 参数

Label | 如果省略, 脚本将返回到正常的退出行为. 否则, 指定标签的名称, 当脚本由于任意原因退出时标签的内容将被执行 (作为一个新 thread/线程) .

重要提示:因为指定的子程序被调用而没有终止该脚本, 想要终止脚本则该子程序必须使用ExitApp命令.可选的 (如同下面的示例那样), OnExit 子程序会显示一个 MsgBox 消息框提示用户确认 -- 只有当用户按下 YES/是 按钮才会执行 ExitApp 命令退出脚本.

#### 备注

当脚本由于任意原因退出时 OnExit 子程序会被调用 (除非脚本是被像结束任务这样杀掉). 每当 #SingleInstance 和 Reload 命令要求终止前一个实例时,子过程也会被调用.

通过 OnMessage(0x11, "WM_QUERYENDSESSION") 脚本可以检测并且可以终止系统关闭或注销操作.

OnExit thread/线程 不服从于 #MaxThreads (需要时它总是会运行). 此外, 当它运行的时候, 它不会被任何其他 线程 中断, 包括 热键, 自定义菜单项, 和 定时执行的子程序. 然而, 如果用户在托盘菜单或主菜单中选择Exit , 或者通过 Reload 或 #SingleInstance 命令要求脚本终止时, 它将会终止执行 (同时脚本将退出). 因此, OnExit 子程序应该设计成快速结束除非用户明白自己正在做什么.

如果 OnExit thread 遇到诸如运行时错误的失败状况, 脚本将终止. 这样可以避免有问题的 OnExit 子程序使得脚本无法终止的情况出现.

如果 OnExit 子程序是由指定退出码的 Exit 或 ExitApp 命令运行的, 退出码被忽略. OnExit 子过程通过 ExitApp命令可以指定一个新的退出码.

每当脚本退出尝试调用 OnExit 子过程时, 这时开启了所有命令的默认设置, 例如 SendMode命令. 这些默认值可以通过 auto-execute section改变.

内置变量 A_ExitReason 为空, 除非 OnExit 子过程正在运行或者在之前的退出中至少调用一次.. 如果不是空的, 它将被设为下列单词中的一个:

Logoff | 用户正在注销.
Shutdown | 系统将被关闭或重启, 例如通过 Shutdown 命令.
Close | 脚本接收到 WM_CLOSE 或 WM_QUIT 消息, 出现一个致命错误, 或者被以其他方式关闭. 尽管这些情况都是很少见的, WM_CLOSE 消息可能是由脚本主窗口使用的 WinClose 命令发出的. 为了避免这种情况, 通过 Send, !{{/0}F4} 命令关闭主窗口.
Error | 在一个没有热键并且不是 持续 运行的脚本中发生了运行时错误. 运行时错误的一个例子是 Run/RunWait 命令无法运行指定的程序或打开指定的文档.
Menu | 用户在主窗口的菜单或标准托盘菜单中选择了退出.
Exit | 使用了 Exit 或 ExitApp 命令 (包括 自定义菜单项).
Reload | 脚本被 Reload 命令或菜单项重载.
Single | 由于 #SingleInstance 命令的结果, 脚本被它自身的一个新实例代替.

#### 相关

OnMessage(), RegisterCallback(), OnClipboardChange, ExitApp, Shutdown, #Persistent, Threads, Gosub, Return, Menu

#### 示例

    #Persistent  ; For demonstration purposes, keep the script running if the user chooses "No".
    OnExit, ExitSub
    返回
    ExitSub:
    if A_ExitReason not in Logoff,Shutdown  ; Avoid spaces around the comma in this line.
    {
        MsgBox, 4, , Are you sure you want to exit?
        IfMsgBox, No
    返回}
    ExitApp  ; The only way for an OnExit script to terminate itself is to use ExitApp in the OnExit subroutine.