Jump to content

Exit Register


seadoggie01
 Share

Recommended Posts

OnAutoItExitRegister is nice, but it doesn't quite hit the spot for me. What if I want to save and close an Excel document when the script ends? Then I have to make the document global (possibly the Excel object as well) and write a separate function. I'm lazy and don't like separate functions. Enter Sandman ExitRegister

Register functions with parameters to be run on script exit. If you want to, you can even insert them at the beginning. For our Excel example:

Spoiler
#include <Excel.au3>
#include <ExitRegister.au3>

Main()

Func Main()
    
    If 1 <> MsgBox(1, "Warning!", "Continuing will cause all of your Excel workbooks to be closed. Proceede with caution! Press cancel to quit.") Then Exit
    
    ; Open Excel
    Local $oExcel = _Excel_Open()
    If @error Then Exit ConsoleWrite("_Excel_Open - Error: " & @error & " Extended: " & @extended)
    
    ; Register Excel to close when the script is over
    _ExitRegister_Add(_Excel_Close, $oExcel, False, True)
    If @error Then Exit ConsoleWrite("_ExitRegister_Add - Error: " & @error & " Extended: " & @extended)

    ; Open a new workbook
    Local $oBook = _Excel_BookNew($oExcel, 1)
    If @error Then Exit ConsoleWrite("_Excel_BookNew - Error: " & @error & " Extended: " & @extended)
    
    ; Register the book to be closed BEFORE Excel is closed
    _ExitRegister_Insert(0, _Excel_BookClose, $oBook, False)
    If @error Then Exit ConsoleWrite("_ExitRegister_Insert - Error: " & @error & " Extended: " & @extended)
    
    ; Do some other things... like take a nap?
    Sleep(5000)

EndFunc

 

Now I can sleep easy knowing that Excel will be closed even if the workbook fails to be created and the script exits early.

Spoiler
#include-once

#include <Array.au3>
#include <CustomDebugging.au3>

Global $__g_aExitFunctions[0][2]; = [[Function handle, array of arguments to pass], ... ]

; #FUNCTION# ====================================================================================================================
; Name ..........: _ExitRegister_Add
; Description ...: Adds a function to the end of the list to be called on Exit
; Syntax ........: _ExitRegister_Add($hFunction[, $vArg1 = Default[, ... $vArg10 = Default]])
; Parameters ....: $hFunction           - a handle value.
;                  $vArg1               - [optional] a variant value. Default is Default.
;                  $vArg2               - [optional] a variant value. Default is Default.
;                  $vArg3               - [optional] a variant value. Default is Default.
;                  $vArg4               - [optional] a variant value. Default is Default.
;                  $vArg5               - [optional] a variant value. Default is Default.
;                  $vArg6               - [optional] a variant value. Default is Default.
;                  $vArg7               - [optional] a variant value. Default is Default.
;                  $vArg8               - [optional] a variant value. Default is Default.
;                  $vArg9               - [optional] a variant value. Default is Default.
;                  $vArg10              - [optional] a variant value. Default is Default.
; Return values .: Success - True
;                  Failure - False and sets @error:
;                  |1 - $hFunction isn't a function
; Author ........: Seadoggie01
; Modified ......: March 12, 2021
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _ExitRegister_Add($hFunction, $vArg1 = Default, $vArg2 = Default, $vArg3 = Default, $vArg4 = Default, $vArg5 = Default, $vArg6 = Default, $vArg7 = Default, $vArg8 = Default, $vArg9 = Default, $vArg10 = Default)

    Local $vRet = __ExitRegister_Add(Default, $hFunction, @NumParams, $vArg1, $vArg2, $vArg3, $vArg4, $vArg5, $vArg6, $vArg7, $vArg8, $vArg9, $vArg10)
    Return SetError(@error, @extended, $vRet)

EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _ExitRegister_Insert
; Description ...: Inserts an item at the specified location on the list of functions to be called on exit
; Syntax ........: _ExitRegister_Insert($iIndex, $hFunction[, $vArg1 = Default[, ... $vArg10 = Default]])
; Parameters ....: $iIndex              - an integer value.
;                  $hFunction           - a handle value.
;                  $vArg1               - [optional] a variant value. Default is Default.
;                  $vArg2               - [optional] a variant value. Default is Default.
;                  $vArg3               - [optional] a variant value. Default is Default.
;                  $vArg4               - [optional] a variant value. Default is Default.
;                  $vArg5               - [optional] a variant value. Default is Default.
;                  $vArg6               - [optional] a variant value. Default is Default.
;                  $vArg7               - [optional] a variant value. Default is Default.
;                  $vArg8               - [optional] a variant value. Default is Default.
;                  $vArg9               - [optional] a variant value. Default is Default.
;                  $vArg10              - [optional] a variant value. Default is Default.
; Return values .: Success - True
;                  Failure - False and sets @error:
;                  |1 - $hFunction isn't a function
;                  |2 - $iIndex is out of bounds of the array of exit functions
; Author ........: Seadoggie01
; Modified ......: March 12, 2021
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _ExitRegister_Insert($iIndex, $hFunction, $vArg1 = Default, $vArg2 = Default, $vArg3 = Default, $vArg4 = Default, $vArg5 = Default, $vArg6 = Default, $vArg7 = Default, $vArg8 = Default, $vArg9 = Default, $vArg10 = Default)

    If $iIndex > (UBound($__g_aExitFunctions) - 1) Then Return SetError(2, 0, False)
    If $iIndex < 0 Then Return SetError(2, 0, False)

    Local $vRet = __ExitRegister_Add($iIndex, $hFunction, @NumParams - 1, $vArg1, $vArg2, $vArg3, $vArg4, $vArg5, $vArg6, $vArg7, $vArg8, $vArg9, $vArg10)
    Return SetError(@error, @extended, $vRet)

EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _ExitRegister_Remove
; Description ...: Removes a function from the list
; Syntax ........: _ExitRegister_Remove($hFunction[, $iRemoveIndex = Default])
; Parameters ....: $hFunction           - a handle value.
;                  $iRemoveIndex        - [optional] index of function to remove. Default removes all instances.
; Return values .: Success - True
;                  Failure - False and sets @error:
;                  |1 - $hFunction is not a function
;                  |2 - $hFunction wasn't found (no changes were made)
; Author ........: Seadoggie01
; Modified ......: March 12, 2021
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _ExitRegister_Remove($hFunction, $iRemoveIndex = Default)

    If Not IsFunc($hFunction) Then Return SetError(1, 0, False)
    Local $bRemoveAll = IsKeyword($iRemoveIndex)

    Local $iFound = 0, $iNext = 0
    For $i=0 To UBound($__g_aExitFunctions) - 1
        ; If the next index doesn't match
        If Not ($i = $iNext) Then
            ; Copy the values down
            $__g_aExitFunctions[$iNext][0] = $__g_aExitFunctions[$i][0]
            $__g_aExitFunctions[$iNext][1] = $__g_aExitFunctions[$i][1]
        EndIf
        ; if this is the function
        If $__g_aExitFunctions[$i][0] = $hFunction Then
            ; If we want to remove this function, decrease the array size
            If $iFound = $iRemoveIndex Or $bRemoveAll Then $iNext -= 1
            $iFound += 1
        EndIf
        $iNext += 1
    Next
    ; Resize the array
    ReDim $__g_aExitFunctions[$iNext][2]
    ; If the function wasn't found, return an error
    If $iNext = $i Then Return SetError(2, 0, False)
    Return True

EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _ExitRegister_RemoveAll
; Description ...: Clears the list of functions
; Syntax ........: _ExitRegister_RemoveAll()
; Parameters ....: None
; Return values .: True
; Author ........: Seadoggie01
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _ExitRegister_RemoveAll()

    ReDim $__g_aExitFunctions[0][2]
    Return True

EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: __ExitRegister_Add
; Description ...: Adds a new function and parameters to the list to be executed
; Syntax ........: __ExitRegister_Add($iIndex, $hFunction, $iNumParams[, $vArg1 = Default[, $vArg2 = Default[, $vArg3 = Default[,
;                  $vArg4 = Default[, $vArg5 = Default[, $vArg6 = Default[, $vArg7 = Default[, $vArg8 = Default[,
;                  $vArg9 = Default[, $vArg10 = Default]]]]]]]]]])
; Parameters ....: $iIndex              - an integer value.
;                  $hFunction           - a handle value.
;                  $iNumParams          - an integer value.
;                  $vArg1               - [optional] a variant value. Default is Default.
;                  $vArg2               - [optional] a variant value. Default is Default.
;                  $vArg3               - [optional] a variant value. Default is Default.
;                  $vArg4               - [optional] a variant value. Default is Default.
;                  $vArg5               - [optional] a variant value. Default is Default.
;                  $vArg6               - [optional] a variant value. Default is Default.
;                  $vArg7               - [optional] a variant value. Default is Default.
;                  $vArg8               - [optional] a variant value. Default is Default.
;                  $vArg9               - [optional] a variant value. Default is Default.
;                  $vArg10              - [optional] a variant value. Default is Default.
; Return values .: Success - True
;                  Failure - False and sets @error:
;                  |1 - $hFunction isn't a function
; Author ........: Seadoggie01
; Modified ......: March 12, 2021
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func __ExitRegister_Add($iIndex, $hFunction, $iNumParams, $vArg1 = Default, $vArg2 = Default, $vArg3 = Default, $vArg4 = Default, $vArg5 = Default, $vArg6 = Default, $vArg7 = Default, $vArg8 = Default, $vArg9 = Default, $vArg10 = Default)
    #forceref $vArg1, $vArg2, $vArg3, $vArg4, $vArg5, $vArg6, $vArg7, $vArg8, $vArg9, $vArg10

    ; Only deal with actual functions... otherwise I'd have to deal with more calling errors
    If Not IsFunc($hFunction) Then Return SetError(1, 0, False)

    Static $bExitRegistered = False
    ; Register the helper function if it's not registered yet
    If Not $bExitRegistered Then OnAutoItExitRegister("__ExitRegister_Exit")
    $bExitRegistered = True
    If IsKeyword($iIndex) Then $iIndex = UBound($__g_aExitFunctions)

    Local $aArgs[2]
    ; If the user preped the array themselves
    If IsArray($vArg1) And $vArg1[0] = "CallArgArray" Then
        $aArgs = $vArg1
    Else
        ; Create a CallArgArray for the user
        ReDim $aArgs[$iNumParams]
        $aArgs[0] = "CallArgArray"
        For $i=1 To UBound($aArgs) - 1
            $aArgs[$i] = Eval("vArg" & $i)
        Next
    EndIf

    ; Add the function and args to the array
    ReDim $__g_aExitFunctions[UBound($__g_aExitFunctions) + 1][2]
    ; Fun array suffle
    Local $hOldFunc, $aOldArgs
    For $i=$iIndex To UBound($__g_aExitFunctions) - 1
        $hOldFunc = $__g_aExitFunctions[$i][0]
        $aOldArgs = $__g_aExitFunctions[$i][1]
        $__g_aExitFunctions[$i][0] = $hFunction
        $__g_aExitFunctions[$i][1] = $aArgs
        $hFunction = $hOldFunc
        $aArgs = $aOldArgs
    Next

    Return True

EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: __ExitRegister_Exit
; Description ...: Called on exit to execute function list
; Syntax ........: __ExitRegister_Exit()
; Parameters ....: None
; Return values .: None
; Author ........: Seadoggie01
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func __ExitRegister_Exit()

    Local $sFunc, $iErr, $iExt, $vRet
    For $i=0 To UBound($__g_aExitFunctions) - 1
        $sFunc = FuncName($__g_aExitFunctions[$i][0])
        $vRet = Call($sFunc, $__g_aExitFunctions[$i][1])
        $iErr = @error
        $iExt = @extended
        If $iErr = 0xDEAD And $iExt = 0xBEEF Then
            ConsoleWrite("!> Function " & $sFunc & " doesn't exist or invalid number of parameters passed." & @CRLF)
            ContinueLoop
        EndIf
                        ConsoleWrite("> Function: " & $sFunc & @CRLF)
        If IsArray($vRet) Then
            ConsoleWrite("> Returned: " & _ArrayToString($vRet) & @CRLF)
        Else
            ConsoleWrite("> Returned: " & $vRet & @CRLF)
        EndIf
        If $iErr Then   ConsoleWrite("> Error:    " & $iErr & @CRLF)
        If $iExt Then   ConsoleWrite("> Extended: " & $iExt & @CRLF)
        ConsoleWrite(@CRLF)
    Next

EndFunc

 

Documentation to come soon... I hope... 🤥 Updated with documentation.

I forgot to mention, I only added 10 parameters for the exit functions, but his can be expanded very quickly, so let me know if you need more! I don't think I've ever used more than 10 parameters on a function (before now)

Edited by seadoggie01
Do you even run your code before you post it? Maybe...

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...