Jump to content

CD Autorun for multiple script execution


MHz
 Share

Recommended Posts

Preview:

post-2709-1177319057_thumb.jpg

Summary:

I created a simple Autorun.exe for installing software easily using AutoIt to power the Au3/A3x install scripts that handle the software executions. The Autorun.exe searches for all subdirs and then searches for Au3/A3x scripts found under those subdirs and populates a treeview. The subdir names are used for the treeview's root branches. Sound simple enough? As each checkbox is and then the final execute button is pressed, then all the selected scripts will execute one after the other showing exitcodes, You can write a file to tempdir from one of the install scripts named ~NeedRestart.txt and if found by the autorun.exe at end of script executions, then it will ask user of reboot needed to complete. A general cleanup script is used also if the install scripts are unsuitable for the task. You can find Autorun.au3 in the include folder which as to when compiled with Scite4AutoIt3, will move up one folder to inline with autorun.inf and include folder. It's is simple but effective for a batch run AutoIt of scripts.

Thanks to Holger's Tri-State Checkbox UDF and to Valik's RefreshSystemTray UDF used to assist operation for this script.

I uploaded a sample with a couple of small apps (CCleaner & USDownloader) for live preview if interested.

Edit:

1. Added sample file size.

2. Worth mentioning that SendToA3X makes install scripts from the Identify Installer item. The install scripts created are perfect for using with this application. :(

Sample:

http://www.mytempdir.com/1304238 (2.57Mb)

Source:

autorun_source.zip

Script:

#Compiler_Res_Description=Software Deployment
#Compiler_UseUpx=n
#Compiler_Run_After=move "%out%" "%scriptdir%\..\"

#NoTrayIcon
#include <Constants.au3>
#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#include <Misc.au3>
#include <RefreshSystemTray.au3>
#include <TristateTreeViewLib.au3>

Global Const $TITLE_GUI = 'Software Deployment'
; Only 1 instance of this script to execute at once.
If Not _Singleton($TITLE_GUI, 1) Then
    Sleep(500)
    WinActivate($TITLE_GUI)
    Exit
EndIf
; Set @ScriptDir as working directory.
If @ScriptDir <> @WorkingDir Then
    FileChangeDir(@ScriptDir)
EndIf
; Execute external AutoIt script if drag'n'drop is used.
If $CMDLINE[0] And StringRight($CMDLINE[1], 4) = '.au3' Then
    RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $CMDLINE[1] & '"')
    Exit
EndIf
; FileInstall Tri-State BMP's pictures.
Global $sStateIconFile = @ScriptDir & '\Include\modern.bmp'
If Not FileExists(@ScriptDir & '\Include') And _
    Not FileExists(@ScriptDir & '\Common_Functions.au3') Then
    DirCreate(@ScriptDir & '\Include')
    FileInstall('colorful.bmp', @ScriptDir & '\Include\')
    FileInstall('modern.bmp', @ScriptDir & '\Include\')
    FileInstall('simple.bmp', @ScriptDir & '\Include\')
    FileInstall('cleanup.au3', @ScriptDir & '\Include\')
EndIf

#region - GUI Create
; Set XP+ theme to allow controls to show colour. 
SetThemeAppProperties(3)
Global $style = BitOR($TVS_CHECKBOXES, $TVS_HASBUTTONS, $TVS_DISABLEDRAGDROP, $TVS_LINESATROOT)
Global Const $HEIGHT_ADJUST = 38
$handle_gui = GUICreate($TITLE_GUI, 450, 255 + $HEIGHT_ADJUST)
$treeview_main = GUICtrlCreateTreeView(10, 10, 430, 200 + $HEIGHT_ADJUST, $style, $WS_EX_CLIENTEDGE)
; Return a @CRLF deliminated string of subfolders
$folders = _SubFolders(@ScriptDir)
$items = StringSplit($folders, @CRLF, 1)
$folders = ''
; Initalize array for groups
Global $handle_subfolder[$items[0]+1]
Global $handle_script[1], $k = 0
; Fill the treeview with items.
For $i = 1 To $items[0]
    $handle_subfolder[$i] = GUICtrlCreateTreeViewItem($items[$i], $treeview_main)
    GUICtrlSetState(Default, $GUI_HIDE)
    $scripts = _ScriptSearchPath_Relative($items[$i])
    If Not @error Then
        ReDim $handle_script[UBound($handle_script) + UBound($scripts) -1]
        For $j = 1 To $scripts[0]
            $handle_script[$k] = GUICtrlCreateTreeViewItem(StringTrimRight(StringReplace($scripts[$j], '_', ' '), 4), $handle_subfolder[$i])
            $k += 1
        Next
    EndIf
Next
; Show AutoIt version used to power the scripts.
$label_autoit = GUICtrlCreateLabel('Scripts powered by AutoIt ' & FileGetVersion(@AutoItExe), 20, 225 + $HEIGHT_ADJUST, 220, 20)
GUICtrlSetColor(Default, 0x010080)
GUICtrlSetFont(Default, 9, 800)
$button_execute = GUICtrlCreateButton('E&xecute', 350, 220 + $HEIGHT_ADJUST, 80)
LoadStateImage($treeview_main, $sStateIconFile)
GUICtrlSetState($button_execute, $GUI_FOCUS)
GUISetState()
SelectStandard()
ProcessSetPriority(@AutoItPID, 0)
#endregion

Global $progress_count_total = 0, $progress_count_current = 0
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case -8 To -7
            ; Remove focus highlighting from treeview.
            If GUICtrlRead($treeview_main) Then
                GUICtrlSetState($button_execute, $GUI_FOCUS)
            EndIf
        Case -20 To 0
            ; Save CPU on unneeded messages
            ContinueLoop
        Case $button_execute
            $exitcode_text = ''
            ; Validate if any items are indeed checked for execution. 
            For $i = 0 To UBound($handle_script) -1
                If BitAnd(GUICtrlRead($handle_script[$i]), $GUI_CHECKED) Then
                    $Path = @ScriptDir & '\' & GUICtrlRead(_GUICtrlTreeViewGetParentID($treeview_main, $handle_script[$i]), 1) & '\' & StringReplace(GUICtrlRead($handle_script[$i], 1), ' ', '_') & '.au3'
                    If FileExists($path) Then
                        $progress_count_total += 1
                    EndIf
                EndIf
            Next
            If $progress_count_total = 0 Then
                ; Nothing to execute so alert user to nothing to do.
                SplashTextOn('No Selections Detected', 'Nothing to install', 200, 80, Default, Default, 32)
                Sleep(2000)
                SplashOff()
                ContinueLoop
            Else
                ; Show cancel option for a few seconds.
                $time = TimerInit()
                GUICtrlSetData($button_execute, '&Cancel')
                While TimerDiff($time) < 3000
                    If GUIGetMsg() = $button_execute Then
                        GUICtrlSetData($button_execute, 'E&xecute')
                        ContinueLoop 2
                    EndIf
                WEnd
            EndIf
            GUIctrlSetState($button_execute, $GUI_HIDE)
            GUICtrlSetState($label_autoit, $GUI_HIDE)
            ; Prepare progress with labels to show current script in execution. 
            $handle_progress = GUICtrlCreateProgress(10, 210 + $HEIGHT_ADJUST, 430, 14)
            $handle_status = GUICtrlCreateLabel('', 10, 232 + $HEIGHT_ADJUST, 330, 18)
            GUICtrlSetFont($handle_status, 9, 600)
            ; Execute selected scripts, get exitcode and update Gui.
            For $i = 0 To UBound($handle_script) -1
                If BitAnd(GUICtrlRead($handle_script[$i]), $GUI_CHECKED) Then
                    $handle_text = GUICtrlRead($handle_script[$i], 1)
                    $path = @ScriptDir & '\' & GUICtrlRead(_GUICtrlTreeViewGetParentID($treeview_main, $handle_script[$i]), 1) & '\' & StringReplace($handle_text, ' ', '_') & '.au3'
                    If Not FileExists($path) Then
                        ; If not au3, then perhaps a3x.
                        $path = StringTrimLeft($path, 4) & '.a3x'
                    EndIf
                    ; Execute script routine.
                    If FileExists($path) Then
                        GUICtrlSetData($handle_status, $handle_text)
                        $progress_count_current +=1
                        $progress_percent = _Percent($progress_count_total, $progress_count_current)
                        GUICtrlSetData($handle_progress, $progress_percent)
                        $exitcode = RunWait(@AutoItExe & ' /AutoIt3ExecuteScript "' & $path & '"')
                    Else
                        $exitcode = 911
                    EndIf
                    ; Update Gui with red or green font depending on exitcode returned.
                    _GUICtrlTreeViewSetText($treeview_main, $handle_script[$i], 'Exitcode : ' & $exitcode & '  ~  ' & $handle_text)
                    If $exitcode Then
                        GUICtrlSetColor($handle_script[$i], 0xCC0000)
                        $exitcode_text &= 'Exitcode : ' & $exitcode & '  ~  ' & $handle_text & @CRLF
                    Else
                        GUICtrlSetColor($handle_script[$i], 0x007700)
                    EndIf
                EndIf
            Next
            ; General cleanup script that the other scripts do not.
            If FileExists(@ScriptDir & '\Include\Cleanup.au3') Then
                GUICtrlSetData($handle_status, 'Cleanup in progress...')
                RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & @ScriptDir & '\Include\Cleanup.au3' & '"')
            EndIf
            ; Remove dead icons from systray.
            _RefreshSystemTray()
            GUICtrlDelete($handle_status)
            GUICtrlDelete($handle_progress)
            GUICtrlSetState($label_autoit, $GUI_SHOW)
            ; Only message errors to user if any happened.
            If $exitcode_text Then
                MsgBox(0x40030, 'Script Exitcode errors with...', $exitcode_text)
                $exitcode_text = ''
                Sleep(1000)
            EndIf
            GUICtrlSetData($button_execute, 'E&xecute')
            GUIctrlSetState($button_execute, $GUI_SHOW)
            $progress_count_current = 0
            $progress_count_total = 0
            ; Only message user if reboot is needed.
            If FileExists(@TempDir & '\~NeedRestart.txt') Then
                FileDelete(@TempDir & '\~NeedRestart.txt')
                If MsgBox(0x40024, $TITLE_GUI & ' Complete', 'System requires a restart' & @CRLF & 'Restart now?') = $IDYES Then
                    Shutdown(2)
                    Exit
                EndIf
            EndIf
    EndSwitch
WEnd

Exit

Func SetThemeAppProperties($nFlags)
    ; Additional info to SetThemeProperties-value:
    ; 0 = disallow visual styles for all controls/nonclient areas
    ; 1 = disallow for nonclient areas (like border, etc)
    ; 2 = disallow for normal controls
    ; 4 = disallow for web contents.
    If FileExists(@SystemDir & '\uxtheme.dll') Then
        DllCall('uxtheme.dll', 'none', 'SetThemeAppProperties', 'int', $nFlags)
    EndIf
EndFunc

Func _SubFolders($sFolderPath)
    ; Return all sub folders with the chosen folder.
    Local $cCollection, $oFSO, $oItem, $oFolderPath, $sTotal
    $oFSO = ObjCreate('Scripting.FileSystemObject')
    If Not @error Then
        $oFolderPath = $oFSO.GetFolder($sFolderPath)
        $cCollection = $oFolderPath.SubFolders
        For $oItem In $cCollection
            Switch $oItem.Name
                ; SubFolders to skip.
                Case 'Xtras', 'Include'
                    ContinueLoop
            EndSwitch
            $sTotal &= $oItem.Name & @CRLF
        Next
        $oFSO = ''
        Return StringStripWS($sTotal, 3)
    Else
        Return SetError(1, 0, '')
    EndIf
EndFunc

Func _ScriptSearchPath_Relative($dir_parameter)
    ; Find all Au3 script in a chosen folder.
    Local $file_found, $file_split, $file_total, $handle_search
    Local $dir_workingdir = @WorkingDir
    If StringRight($dir_parameter, 1) <> '\' Then
        $dir_parameter = $dir_parameter & '\'
    EndIf
    If FileChangeDir($dir_parameter) Then
        $handle_search = FileFindFirstFile('*.a*')
        If $handle_search <> -1 Then
            While 1
                $file_found = FileFindNextFile($handle_search)
                If @error Then ExitLoop
                ; Skip non au3 or a3x files and scripts starting with 2 underscores.
                If StringRight($file_found, 3) <> 'au3' And _
                    StringRight($file_found, 3) <> 'a3x' Or _
                    StringLeft($file_found, 2) = '__' Or _
                    $file_found = @ScriptName Then
                    ContinueLoop
                EndIf
                $file_total &= $file_found & '|'
            WEnd
            FileClose($handle_search)
            FileChangeDir($dir_workingdir)
            If StringRight($file_total, 1) = '|' Then
                $file_total = StringTrimRight($file_total, 1)
            EndIf
            $file_split = StringSplit($file_total, '|')
            Return $file_split
        EndIf
        FileChangeDir($dir_workingdir)
    EndIf
    Return SetError(2, 0, '')
EndFunc

Func RemoveCheckbox($nTV, $nID)
    ; Remove check from treeview.
    Local $hItem = GUICtrlGetHandle($nID)
    If $hItem = 0 Then $hItem = $nID
    Local $stTVITEM = DllStructCreate('uint;uint;uint;uint;ptr;int;int;int;int;uint;int')
    DllStructSetData($stTVITEM, 1, $TVIF_STATE)
    DllStructSetData($stTVITEM, 2, $hItem)
    DllStructSetData($stTVITEM, 3, 0)
    DllStructSetData($stTVITEM, 4, $TVIS_STATEIMAGEMASK)
    GUICtrlSendMsg($nTV, $TVM_SETITEM, 0, DllStructGetPtr($stTVITEM))
EndFunc

Func SelectStandard()
    ; Checks/Unchecks treeview items.
    For $i = 0 To UBound($handle_subfolder) -1
        If BitAnd(GUICtrlRead($handle_subfolder[$i]), $GUI_CHECKED) Then
            MyCtrlSetItemState($treeview_main, $i, $GUI_CHECKED)
        EndIf
    Next
EndFunc

Func _Percent($total, $part)
    ; Simple calculation for progressbar.
    Return Int(100/$total*$part)
EndFunc

Func OnAutoItExit()
    ; Final cleanup to finish.
    FileDelete(@TempDir & '\~NeedRestart.txt')
EndFunc

:shocked:

Edited by MHz
Link to comment
Share on other sites

  • 2 weeks later...

Most probably I will not use it but I like to see (and learn from) clever Autoit scripts and new cool ideas for using Autoit :)

Anyway to make it so that you can only select 1 app within a group? Maybe by the way the AU3 file is named preceeded with a _??

Link to comment
Share on other sites

Anyway to make it so that you can only select 1 app within a group? Maybe by the way the AU3 file is named preceeded with a _??

All my install scripts preceed with a underscore by default. If you want a script to be not detected, then use 2 preceeding underscores and it will be skipped over during the script file search.

:)

Link to comment
Share on other sites

All my install scripts preceed with a underscore by default. If you want a script to be not detected, then use 2 preceeding underscores and it will be skipped over during the script file search.

:)

What I was thinking that in a group you could have lets say 3 apps but you can only select 1 of them. So only 1 checkmark can populate an app in that group. if you check another one in that group then all other checkmarks are cleared out.

Link to comment
Share on other sites

So you want a radio button effect in each group. You would need code to monitor any clicks to the checkboxes and if another in the group is checked, then uncheck it. It is possible, but not normal for a checkbox to do that, as why we have radio controls. Not sure if a treeview can support radio controls as I have not seen one before AFAIK.

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...