OnExit can be used as a function or command, although the former is recommended for new scripts. As a function, it registers a function to be called automatically whenever the script exits. As a command, it registers a subroutine to be called automatically whenever the script exits.

OnExit Function [v1.1.20+]

Registers a function to be called automatically whenever the script exits.

OnExit(Callback , AddRemove)



A function name or function object to call. To pass a literal function name, enclose it in quotes.

The callback accepts two parameters and can be defined as follows:

MyCallback(ExitReason, ExitCode) { ...

Although the names you give the parameters do not matter, the following values are sequentially assigned to them:

  1. The exit reason (one of the words from the table below).
  2. The exit code passed to Exit or ExitApp.

You can omit one or more parameters from the end of the callback's parameter list if the corresponding information is not needed.

The callback can return a non-zero integer to prevent the script from exiting (with some rare exceptions) and calling more callbacks. Otherwise, the script exits after all registered callbacks are called.


If omitted, it defaults to 1. Otherwise, specify one of the following numbers:

If a subroutine has been registered by the OnExit command below, that subroutine is always called first.


Any number of callbacks can be registered. If a subroutine is also registered (by the OnExit command below), the callbacks are called after the subroutine calls ExitApp. A callback usually should not call ExitApp; if it does, the script terminates immediately.

OnExit Command

Registers a subroutine to be called automatically whenever the script exits.

Deprecated: This command is not recommended for use in new scripts. Use the OnExit function described above instead to reduce the risk of accidentally creating a script which can't be exited, and ensures that the exit code passed to Exit or ExitApp is preserved.

OnExit , Label



If blank or omitted, any previously registered subroutine is unregistered. Otherwise, specify the label of the subroutine whose contents will be executed (as a new thread) when the script exits by any means.


Since the registered subroutine is called instead of terminating the script, that subroutine must use ExitApp if termination is desired.

The built-in variable A_ExitReason is blank unless the registered subroutine is currently running or has been called at least once by a prior exit attempt. If not blank, it is one of the words from the table below.


The callback or subroutine is called when the script exits by any means (except when it is killed by something like "End Task"). It is also called whenever #SingleInstance and Reload ask a previous instance to terminate.

A script can detect and optionally abort a system shutdown or logoff via OnMessage(0x0011, "WM_QUERYENDSESSION") (see OnMessage example #2 for a working script).

The OnExit thread does not obey #MaxThreads (it will always launch when needed). In addition, while it is running, it cannot be interrupted by any thread, including hotkeys, custom menu items, and timed subroutines. However, it will be interrupted (and the script will terminate) if the user chooses Exit from the tray menu or main menu, or the script is asked to terminate as a result of Reload or #SingleInstance. Because of this, the callback or subroutine should be designed to finish quickly unless the user is aware of what it is doing.

If the OnExit thread encounters a failure condition such as a runtime error, the script will terminate. This prevents a flawed callback or subroutine from making a script impossible to terminate.

If the OnExit thread was launched due to Exit or ExitApp that specified an exit code, in v1.1.19 and earlier that code is ignored and no longer available. In [v1.1.20+] the initial exit code is used unless overridden by calling ExitApp with a new exit code.

Whenever an exit attempt is made, each callback or subroutine starts off fresh with the default values for settings such as SendMode. These defaults can be changed in the auto-execute section.

Exit Reasons

Reason Description
Logoff The user is logging off.
Shutdown The system is being shut down or restarted, such as by the Shutdown command.

The script was sent a WM_CLOSE or WM_QUIT message, had a critical error, or is being closed in some other way. Although all of these are unusual, WM_CLOSE might be caused by WinClose having been used on the script's main window. To close (hide) the window without terminating the script, use WinHide.

If the script is exiting due to a critical error or its main window being destroyed, it will unconditionally terminate after the OnExit thread completes.

If the main window is being destroyed, it may still exist but cannot be displayed. This condition can be detected by monitoring the WM_DESTROY message with OnMessage().

Error A runtime error occurred in a script that has no hotkeys and that is not persistent. An example of a runtime error is Run/RunWait being unable to launch the specified program or document.
Menu The user selected Exit from the main window's menu or from the standard tray menu.
Exit Exit or ExitApp was used (includes custom menu items).
Reload The script is being reloaded via the Reload command or menu item.
Single The script is being replaced by a new instance of itself as a result of #SingleInstance.

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


Function vs. command.

Despite the different syntax, both examples have the same effect: They ask the user before exiting the script. To test them, right-click the tray icon and click Exit.

#Persistent  ; Prevent the script from exiting automatically.

ExitFunc(ExitReason, ExitCode)
    if ExitReason not in Logoff,Shutdown  ; Avoid spaces around the comma.
        MsgBox, 4, , Are you sure you want to exit?
        IfMsgBox, No
            return 1  ; Callbacks must return non-zero to avoid exit.
    ; Do not call ExitApp -- that would prevent other callbacks from being called.
#Persistent  ; Prevent the script from exiting automatically.
OnExit, ExitSub

if A_ExitReason not in Logoff,Shutdown  ; Avoid spaces around the comma.
    MsgBox, 4, , Are you sure you want to exit?
    IfMsgBox, No
ExitApp  ; A script with an registered subroutine will not terminate unless the subroutine uses ExitApp.

Registers an object to be called on exit.

#Persistent  ; Prevent the script from exiting automatically.
OnExit(ObjBindMethod(MyObject, "Exiting"))

class MyObject
        MsgBox, MyObject is cleaning up prior to exiting...