Jump to content
Sign in to follow this  
jdelaney

Script Compiler 'wrapper'

Recommended Posts

jdelaney

If you have ever tried to auto-compile scripts, you will notice that lots of errors might occur.  I created a little script to attempt upwards of 10x prior to failing out, while closing windows, as they appear.  This stops some automated process from hanging on a window that requires user interaction.  I've tested it in a loop, and was able to successfully compile 50x prior to aborting the cmd loop.

In the script, I'm requiring 3 params passed in, and it's best compiled as a command line exe.

1) the script to compile

2) the path to compile to

3) the version number (this requires the beta version of the AutoIt3Wrapper.exe, which was just released a day or two ago...but you can remove that param, and use aut2exe if desired.)

One other note, I'm moving over the au3 files from a version control system, so they never include the directives for the compiler.  I notice that Autoit3wrapper prepends these, and the last applicable directive is actually used.  You could always add, rather than creating the ini, a line at the end of the file with the true directives you want, so they are always read in.

#include <File.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#RequireAdmin
AutoItSetOption("WinDetectHiddenText", 1)
FileRecycleEmpty()
; Expect one param, the script to compile
If UBound($CmdLine)<>4 Then
    ConsoleWrite("Required param limitations not met...$CmdLineRaw=[" & $CmdLineRaw & "]." & @CRLF)
    ConsoleWrite("Expecting three paramater like: " & @ScriptFullPath & " C:\path\to\script.au3 C:\path\to\output[\] Version" & @CRLF)
    Exit 1
EndIf
$au3File = $CmdLine[1]
$exeOutFolder = $CmdLine[2]
$exeVersion = $CmdLine[3]

$au3Name = ""

; Validate Param1
If Not StringRegExp($au3File, "(?i)\.au3\b",0) Then
    ConsoleWrite("Required param limitations not met, param 1 must include '.au3' extension...$CmdLine[1]=[" & $CmdLine[1] & "]." & @CRLF)
    Exit 1
EndIf

; Grab name of au3 file (used for exe name) and path, for INI
If Not StringRegExp($au3File,"(?i)\\?([^\\]+)\.au3\b",0) Then
    ConsoleWrite("Unable to parse au3 file name from $CmdLine[1]=[" & $CmdLine[1] & "]." & @CRLF)
    Exit 1
Else
    $aTemp = StringRegExp($au3File,"(?i)\\?([^\\]+)\.au3\b",1)
    $au3Name = $aTemp[0]
EndIf

; Validate Param2 (not au3 or exe extention)
If StringRegExp($exeOutFolder, "(?i)\.au3\b|\.exe\b",0) Then
    ConsoleWrite("Required param limitations not met, param 2 must be a folder with/without trailing '\'...$CmdLine[2]=[" & $CmdLine[2] & "]." & @CRLF)
    Exit 1
EndIf

; Validate Param3 ()
If Not StringRegExp($exeVersion, "\d+\.\d+\.\d+\.\d+",0) Then
    ConsoleWrite("Required param limitations not met, param 3 must be a a file version like #+.#+.#+.#+ '\'...$CmdLine[3]=[" & $CmdLine[3] & "]." & @CRLF)
    Exit 1
EndIf

; create var for output file
If StringRight($exeOutFolder,"1") = "\" Then
    $exeOutFile = $exeOutFolder & $au3Name & ".exe"
Else
    If StringLen($exeOutFolder) = 0 Then
        $exeOutFile = $au3Name & ".exe"
    Else
        $exeOutFile = $exeOutFolder & "\" & $au3Name & ".exe"
    EndIf
EndIf

$bExitOnFailure = False
$AutoIT3Wrapper = @ProgramFilesDir & "\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe"
If Not FileExists($AutoIT3Wrapper) Then
    ConsoleWrite("Compiler not found=[" & $AutoIT3Wrapper & "]." & @CRLF)
    Exit 1
EndIf

Global $AutoIT3Wrapper_Version = FileGetVersion ($AutoIT3Wrapper)
ConsoleWrite($AutoIT3Wrapper & " version=[" & $AutoIT3Wrapper_Version & "]" & @CRLF)

;~ $cmd_compile = '"' & @ProgramFilesDir & '\AutoIt3\Aut2Exe\aut2exe.exe" /in "' & $au3File & '" /out "' & $exeOutFile & '"'
$cmd_compile = '"' & $AutoIT3Wrapper & '" /in "' & $au3File & '" /out "' & $exeOutFile & '"'
ConsoleWrite("Starting based on $CmdLineRaw=[" & $CmdLineRaw & "]." & @CRLF)
ConsoleWrite("Executing cmd=[" & $cmd_compile & "]." & @CRLF)
FileSetAttrib($au3File, "-R")
For $i = 1 To 10
    $bSuccess = True
    FileDelete($exeOutFile)
    Sleep(250)
    ConsoleWrite("Attempt=[" & $i & "] to compile au3=[" & $au3File & "]" & @CRLF)
    FileDelete($au3File & ".ini")
    _FileCreate($au3File & ".ini")
    FileWriteLine($au3File & ".ini",  "[Res]" & @CRLF & "Fileversion=" & $exeVersion)
    ; additional cleanup
    $iCounter_aitwrapper = 0

    While ProcessExists("AutoIt3Wrapper.exe") And $iCounter_aitwrapper < 10
        $a1 = ProcessList("AutoIt3Wrapper.exe")
        For $i = 1 To UBound($a1) - 1
            ProcessClose($a1[$i][1])
        Next
        ConsoleWrite("ProcessClose(AutoIt3Wrapper.exe); processlist=[" & UBound($a1) & "]." & @CRLF)
        $iCounter_aitwrapper += 1
        Sleep(500)
    WEnd
    If ProcessExists("AutoIt3Wrapper.exe") Then
        ConsoleWrite("Unable to close all prior running processes=[" & "AutoIt3Wrapper.exe" & "]" & @CRLF)
        Exit 1
    EndIf

    $iCounter_ait2exe = 0
    While ProcessExists("Aut2exe.exe") And $iCounter_ait2exe < 10
        $a2 = ProcessList("Aut2exe.exe")
        $iCounter_ait2exe += 1
        $a2 = ProcessList("Aut2exe.exe")
        For $i = 1 To UBound($a2) - 1
            ProcessClose($a2[$i][1])
        Next
        ConsoleWrite("ProcessClose(Aut2exe.exe); processlist=[" & UBound($a2) & "]." & @CRLF)
        $iCounter_ait2exe += 1
        Sleep(500)
    WEnd
    If ProcessExists("Aut2exe.exe") Then
        ConsoleWrite("Unable to close all prior running processes=[" & "Aut2exe.exe" & "]" & @CRLF)
        Exit 1
    EndIf
    Sleep(250)
    $iCMD_Compiler = Run($cmd_compile)
    If Not $iCMD_Compiler Then
        ConsoleWrite("Unable to Run cmd=[" & $cmd_compile & "]" & @CRLF)
        Exit 1
    EndIf

    $iTimer = TimerInit()

    While ProcessExists($iCMD_Compiler) And TimerDiff($iTimer) < 20000
        $hCMD_Compiler = GetHWND($iCMD_Compiler)

        ; Now, need to check for messages from another process as well...Aut2exe.exe
        $tempA = ProcessList("Aut2exe.exe")
        If UBound($tempA)>1 Then
            $hCMD_Compiler2 = GetHWND($tempA[UBound($tempA)-1][1])
        Else
            $hCMD_Compiler2 = ""
        EndIf

        If Not IsHWnd($hCMD_Compiler) And Not IsHWnd($hCMD_Compiler2) Then ContinueLoop

        If IsHWnd($hCMD_Compiler2) Then
            $bSuccess = False
            $ERROR_title = WinGetTitle($hCMD_Compiler2)
            $ERROR_text = WinGetText($hCMD_Compiler2)
            ConsoleWrite("ERROR occured.  Title=[" & $ERROR_title & "]; Text=[" & StringRegExpReplace($ERROR_text,"[\r\n]+","[@CRLF]") & "]." & @CRLF)
            Select
                Case StringInStr($ERROR_text, "Error opening the destination file")
                    FileSetAttrib($exeOutFile, "-R")
                    ConsoleWrite("Attempting to remove READONLY state of EXE to overwrite." & @CRLF)
                Case StringInStr($ERROR_text, "Error opening the file")
                    ConsoleWrite("File does not exist, exiting." & @CRLF)
                    $bExitOnFailure = True
                Case Else
                    ConsoleWrite("Unknown error, no action performed." & @CRLF)
            EndSelect
            WinClose($hCMD_Compiler2)
            WinClose($hCMD_Compiler)
        EndIf

        If IsHWnd($hCMD_Compiler) Then
            $ERROR_title = WinGetTitle($hCMD_Compiler)
            $ERROR_text = WinGetText($hCMD_Compiler)
            If StringInStr($ERROR_text,"Found INI file containing AutoIt3Wrapper information") Then
                $iTimer2 = TimerInit()
                While WinExists($hCMD_Compiler) And TimerDiff($iTimer2)<2000
                    WinActivate($hCMD_Compiler)
                    ControlFocus($hCMD_Compiler,"",6)
                    ControlClick($hCMD_Compiler,"",6)
                    Sleep (50)
                WEnd
                If WinExists($hCMD_Compiler) Then
                    ConsoleWrite("ERROR occured with wrapperau3.  Unable to click through INI integration message.  Title=[" & $ERROR_title & "]; Text=[" & StringRegExpReplace($ERROR_text,"[\r\n]+","[@CRLF]") & "]." & @CRLF)
                    WinClose($hCMD_Compiler)
                EndIf
            ElseIf StringInStr($ERROR_text,"Found INI file containing OLD AutoIt3Wrapper information") Then
                $iTimer2 = TimerInit()
                While WinExists($hCMD_Compiler) And TimerDiff($iTimer2)<2000
                    WinActivate($hCMD_Compiler)
                    ControlFocus($hCMD_Compiler,"","&No")
                    ControlClick($hCMD_Compiler,"","&No")
                    Sleep (50)
                WEnd
                If WinExists($hCMD_Compiler) Then
                    ConsoleWrite("ERROR occured with wrapperau3.  Unable to click through OLD INI integration message.  Title=[" & $ERROR_title & "]; Text=[" & StringRegExpReplace($ERROR_text,"[\r\n]+","[@CRLF]") & "]." & @CRLF)
                    WinClose($hCMD_Compiler)
                EndIf
            ElseIf StringInStr($ERROR_title,"Select script to Compile") Then
                $bSuccess = False
                $bExitOnFailure = True
                ProcessClose("AutoIt3Wrapper.exe")
                ConsoleWrite("ERROR occured with wrapperau3.  Unable to find au3 file to compile, exiting." & @CRLF)
            Else
                $bSuccess = False
                ConsoleWrite("ERROR occured with wrapperau3.  Title=[" & $ERROR_title & "]; Text=[" & StringRegExpReplace($ERROR_text,"[\r\n]+","[@CRLF]") & "]." & @CRLF)
                ConsoleWrite("ERROR occured.  Title=[" & $ERROR_title & "]; Text=[" & StringRegExpReplace($ERROR_text,"[\r\n]+","[@CRLF]") & "]." & @CRLF)
                ConsoleWrite("Unknown error , no action performed." & @CRLF)
                WinClose($hCMD_Compiler)
            EndIf
        EndIf

        If $bExitOnFailure Then Exit 1
    WEnd

    If $bSuccess And Not ProcessExists($iCMD_Compiler) Then ExitLoop
    If $iCMD_Compiler And ProcessExists($iCMD_Compiler) Then ProcessClose($iCMD_Compiler)
Next

FileSetAttrib($au3File, "+R")
If $bSuccess Then
    ConsoleWrite("Able to compile au3=[" & $au3File & "] to exe=[" & $exeOutFile & "]" & @CRLF)
    Exit 0
Else
    ConsoleWrite("UNable to compile au3=[" & $au3File & "] to exe=[" & $exeOutFile & "]" & @CRLF)
    Exit 1
EndIf


Func GetHWND($iCallersPID)
    Local $tempPID
    Local $data = WinList("[REGEXPTITLE:\w+]")
    For $i = 1 To UBound($data) - 1
        _WinAPI_GetWindowThreadProcessId($data[$i][1], $tempPID)
        If $tempPID<>$iCallersPID Then ContinueLoop
        If Not StringLen(WinGetText($data[$i][1])) Then ContinueLoop
        If StringInStr(WinGetTitle($data[$i][1]),"(" & $AutoIT3Wrapper_Version & ") Processing :") Then ContinueLoop
        Return $data[$i][1]
    Next
    Return False
EndFunc
Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
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
Sign in to follow this  

×