Jump to content

GUICtrlSetOnEvent variables / Application Browser


Recommended Posts

I figured out how to accomplish what I was trying to do by using global variables, so I thought I'd provide the completed script in case anyone else would have use. Basically, I have a collection of unattended installs that I add and update often, so the script is made to be dynamic and read what is available before drawing the treeview. The information is derived from the directory structure and informational files within specific package folders.

Here's what it looks like:

Posted Image

Here is what the directory structure looks like on the share.

\\server\share_folder <- share point
                     \common <- category folder
                            \adobe_reader <- specific application
                            \macromedia_flash <- specific application
                            \etc.. <- specific application

Here is the code I have so far.

;Include required files.
#include <Array.au3>
#include <GUIConstants.au3>

;Set script options.
Opt("TrayIconHide", 1)
Opt("GUIOnEventMode", 1)

;Define global variables.
Global $basePath, $infoParams, $infoElements, $actionElements, $infoLabels, $categories, $packages, $catElements, $catStates, $packElements, $progressBar

;Set variables needed for GUI initialization.
$basePath = @ScriptDir
$infoFile = "install_info.txt"
$infoParams = getInfoParams()
$categories = getCategories($basePath)
Dim $catStates[UBound($categories)]
$packages = getPackages($basePath, $categories, $infoFile)
$packagesInfo = getPackagesInfo($basePath, $categories, $packages, $infoFile, $infoParams)

;Create GUI elements.
$mainWindow = GUICreate("Package Browser", 420, 400)
$treeview = GUICtrlCreateTreeView(10, 30, 200, 305, BitOr($TVS_HASBUTTONS, $TVS_DISABLEDRAGDROP, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES))
$catElements = createCatTreeView($treeview, $categories, $packages)
$packElements = createPackTreeView($catElements, $packages, $packagesInfo)
$infoElements = createGUIInfoElements()
$optionElements = createGUIOptionElements()
$actionElements = createGUIActionElements()
$progressBar =  createGUIProgressBar()

;Set close event.
GUISetOnEvent($GUI_EVENT_CLOSE, "closeClicked")

;Build the GUI.
GUISetState(@SW_SHOW)
While 1
    Sleep(1000) ;Idle around
WEnd

;Define script functions.
Func getInfoParams()
    ;Return the parameters that will be in $infoFile.
    Dim $infoParams[8]
    $infoParams[0] = 7
    $infoParams[1] = "Title"
    $infoParams[2] = "Description"
    $infoParams[3] = "Version"
    $infoParams[4] = "Updated"
    $infoParams[5] = "Install"
    $infoParams[6] = "Parameters"
    $infoParams[7] = "MSIBased"
    Return $infoParams
EndFunc

Func getCategories($basePath)
    ;Returns an array in the format totalCategories, "categoryFolder", "...".
    Local $categories[1] ;Define the categories array.
    $categories[0] = 0 ;Specify the number of categories.
    $catHandle = FileFindFirstFile($basePath & "\*")
    If $catHandle <> -1 Then
        ;Loop through each directory and add it to the $categories array.
        While 1
            $catFolder = FileFindNextFile($catHandle)
            If @error Then ExitLoop
            If $catFolder = "." Or $catFolder = ".." Then ContinueLoop
            If StringInStr(FileGetAttrib($basePath & "\" & $catFolder), "D") = 0 Then ContinueLoop
            ReDim $categories[UBound($categories) + 1]
            $categories[0] = $categories[0] + 1
            $categories[UBound($categories) - 1] = $catFolder
        WEnd
        FileClose($catHandle)
        return $categories
    Else
        ;An error occcured when accessing the direcotry.
        MsgBox(0, "Error", "Unable to access directory (" & $basePath & ") in getCategories.")
        return $categories
    EndIf
EndFunc

Func getPackages($basePath, $categories, $infoFile)
    ;Returns an array in the format totalPackages, "packageFolder:categoryOffset", "...".
    Local $packages[1] ;Define the packages array.
    $packages[0] = 0 ;Specify the number of packages.
    If FileExists($basePath) Then
        ;Continue the script.
        If $categories[0] > 0 Then
            ;At least one category was found.
            For $catCounter = 1 To $categories[0]
                $catHandle = FileFindFirstFile($basePath & "\" & $categories[$catCounter] & "\*")
                If $catHandle <> -1 Then
                    ;Loop through each directory and add it to the $categories array.
                    While 1
                        $packFolder = FileFindNextFile($catHandle)
                        If @error Then ExitLoop
                        If $packFolder = "." Or $packFolder = ".." Then ContinueLoop
                        If StringInStr(FileGetAttrib($basePath & "\" & $categories[$catCounter] & "\" & $packFolder), "D") = 0 Then ContinueLoop
                        If FileExists($basePath & "\" & $categories[$catCounter] & "\" & $packFolder & "\" & $infoFile) = 0 Then ContinueLoop
                        ReDim $packages[UBound($packages) + 1]
                        $packages[0] = $packages[0] + 1
                        $packages[UBound($packages) - 1] = $packFolder & ":" & $catCounter
                    WEnd
                    FileClose($catHandle)
                EndIf
            Next
            return $packages
        Else
            ;No categories were found.
            MsgBox(0, "Error", "No categories found in getPackages.")
        EndIf
    Else
        ;Generate an error and terminate the script.
        MsgBox(0, "Error", "Base path (" & $basePath & ") not found in getPackages."
        Exit
    EndIf
EndFunc

Func getPackagesInfo($basePath, $categories, $packages, $infoFile, $infoParams)
    ;Returns an array in the format totalPackages, "infoParam1`infoParam2`...`.
    Local $packagesInfo[$packages[0] + 1]
    $packagesInfo[0] = $packages[0]
    For $packCounter = 1 To $packages[0]
        $packagesInfo[$packCounter] = ""
        $splitPackage = StringSplit($packages[$packCounter], ":")
        $packageFolder = $splitPackage[1]
        $packageCat = $splitPackage[2]
        $catFolder = $categories[$packageCat]
        For $paramCounter = 1 To UBound($infoParams) - 1
            $packagesInfo[$packCounter] = $packagesInfo[$packCounter] & getParamValue($basePath & "\" & $catFolder & "\" & $packageFolder & "\" & $infoFile, $infoParams[$paramCounter])
            If $paramCounter < UBound($infoParams) - 1 Then
                $packagesInfo[$packCounter] = $packagesInfo[$packCounter] & "`"
            EndIf
        Next
    Next
    ;_ArrayDisplay($packagesInfo, "Packages Info")
    Return $packagesInfo
EndFunc

Func getParamValue($infoPath, $paramName)
    ;Return the specified param value.  Use N/A if not found.
    $paramValue = "N/A"
    If FileExists($infoPath) Then
        $fileHandle = FileOpen($infoPath, 0)
        ; Check if file opened for reading OK
        If $fileHandle <> -1 Then
            While 1
                $line = FileReadLine($fileHandle)
                If @error = -1 Then ExitLoop
                If StringInStr($line, $paramName & "=""") <> 0 Then
                    $startPoint = StringInStr($line, """") + 1
                    $endPoint = StringInStr($line, """", 0, 2) - $startPoint
                    $value = StringMid($line, $startPoint, $endPoint)
                    $paramValue = $value
                EndIf
            Wend
        EndIf
        FileClose($fileHandle)
    EndIf
    return $paramValue
EndFunc

Func createCatTreeView($treeview, $categories, $packages)
    ;For each category with elements, give it an upper level treeview item.
    Local $catElements[1] ;Define the categories array.
    $catElements[0] = 0 ;Specify the number of categories.
    $catTotals = getCatTotals($categories, $packages)
    For $catCounter = 1 To $categories[0]
        ReDim $catElements[UBound($catElements) + 1]
        If $catTotals[$catCounter] > 0 Then
            $catElements[$catCounter] = GUICtrlCreateTreeViewitem($categories[$catCounter], $treeview)
            GUICtrlSetOnEvent($catElements[$catCounter], "categoryClicked")
        Else
            $catElements[$catCounter] = 0
        EndIf
    Next
    Return $catElements
EndFunc

Func createPackTreeView($catElements, $packages, $packagesInfo)
    ;For each of the packages, add it as a sub option for the containing category.
    Local $packElements[1] ;Define the package array.
    $packElements[0] = 0 ;Specify the number of packages.
    For $packCounter = 1 To $packages[0]
        $splitPackage = StringSplit($packages[$packCounter], ":")
        $packageFolder = $splitPackage[1]
        $packageCat = $splitPackage[2]
        ReDim $packElements[UBound($packElements) + 1]
        $packElements[$packCounter] = GUICtrlCreateTreeViewitem($packageFolder, $catElements[$packageCat])
        GUICtrlSetOnEvent($packElements[$packCounter], "packageClicked")
    Next
    Return $packElements
EndFunc

Func createGUIInfoElements()
    ;Create GUI elements for population with information.
    Dim $infoElements[8]
    Dim $infoLabels[2]
    GUICtrlCreateLabel("Select the packages to install", 10, 8, 190, 15)
    $infoElements[0] = 7
    $packageGroup = GUICtrlCreateGroup("Package Information", 220, 25, 190, 80)
    $infoElements[1] = GUICtrlCreateLabel("", 230, 43, 170, 32) ;Title field.
    $infoLabels[0] = GUICtrlCreateLabel("Version:", 230, 63, 50, 16)
    GUICtrlSetState($infoLabels[0], $GUI_HIDE)
    $infoElements[3] = GUICtrlCreateLabel("", 270, 63, 100, 16) ;Version field.
    $infoLabels[1] = GUICtrlCreateLabel("Updated:", 230, 83, 50, 16)
    GUICtrlSetState($infoLabels[1], $GUI_HIDE)
    $infoElements[4] = GUICtrlCreateLabel("", 276, 83, 100, 16) ;Updated field.
    $descriptionGroup = GUICtrlCreateGroup("Package Description", 220, 110, 190, 140)
    $infoElements[2] = GUICtrlCreateLabel("", 230, 128, 170, 120) ;Description field.
    $infoElements[5] = 0
    $infoElements[6] = 0
    $infoElements[7] = 0
    Return $infoElements
EndFunc

Func createGUIOptionElements()
    ;Create GUI elements used to customize program options.
    Dim $optionElements[4]
    $optionElements[0] = 3
    $optionGroup = GUICtrlCreateGroup("Installation Options", 220, 255, 190, 80)
    $optionElements[1] = GUICtrlCreateCheckbox("Copy MSI-based packages", 230, 273, 170, 16)
    GUICtrlSetState($optionELements[1], $GUI_CHECKED)
    $optionElements[2] = GUICtrlCreateCheckbox("Delete existing (if present)", 230, 293, 170, 16)
    $optionElements[3] = GUICtrlCreateCheckbox("Pause after copying", 230, 313, 170, 16)
    Return $optionElements
EndFunc

Func createGUIActionElements()
    ;Create GUI elements used to trigger program actions.
    Dim $actionElements[3]
    $actionElements[0] = 2
    $actionElements[1] = GUICtrlCreateButton("Begin Installation", 102, 368, 110, 25)
    GUICtrlSetOnEvent($actionElements[1], "beginInstallation")
    $actionElements[2] = GUICtrlCreateButton("Close Program", 219, 368, 110, 25)
    GUICtrlSetOnEvent($actionElements[2], "closeClicked")
    Return $actionElements
EndFunc

Func createGUIProgressBar()
    $progressBar = GUICtrlCreateProgress(10, 344, 400, 17)
    Return $progressBar
EndFunc

Func getCatTotals($categories, $packages)
    ;Get the total packages in each category.
    Local $catTotals[$categories[0] + 1]
    $catTotals[0] = $categories[0]
    ;For each of the categories...
    For $catCounter = 1 To $categories[0]
        $catTotals[$catCounter] = 0
        ;Go through each package to see if it is a member of that category.  Increment $catTotals[$catCounter] by 1 if so.
        For $packCounter = 1 To $packages[0]
            $splitPackage = StringSplit($packages[$packCounter], ":")
            $packageFolder = $splitPackage[1]
            $packageCat = $splitPackage[2]
            If $packageCat = $catCounter Then
                $catTotals[$catCounter] = $catTotals[$catCounter] + 1
            EndIf
        Next
    Next
    Return $catTotals
EndFunc

Func categoryClicked()
    ;Nothing yet...
    Dim $catElements, $catStates, $categories, $packElements, $packages, $infoElements, $infoLabels
    $setPackageState = 0
    $catText = ""
    $packText = ""
    ;Clear text defining label areas.
    For $labelCounter = 0 To UBound($infoLabels) - 1
        GUICtrlSetState($infoLabels[$labelCounter], $GUI_HIDE)
    Next
    ;Clear label values if present.
    For $infoCounter = 1 To UBound($infoElements) - 1
        If $infoElements[$infoCounter] <> 0 Then
            GUICtrlSetData($infoElements[$infoCounter], "")
        EndIf
    Next
    ;If the main category was checked, check all packages in it.  If it was unchecked, uncheck all packages.
    For $catCounter = 1 To $categories[0]
        If $catStates[$catCounter] = "" Then
            ;Make $GUI_UNCHECKED be the default category state.
            $catStates[$catCounter] = $GUI_UNCHECKED
        EndIf
        If @GUI_CtrlID = $catElements[$catCounter] Then
            ;Modify the package states only if the category state has actually changed.
            If BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_CHECKED) = $GUI_CHECKED And $catStates[$catCounter] <> BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_CHECKED) Then
                $catStates[$catCounter] = BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_CHECKED)
                $setPackageState = $GUI_CHECKED
            ElseIf BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_UNCHECKED) = $GUI_UNCHECKED And $catStates[$catCounter] <> BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_UNCHECKED) Then
                $catStates[$catCounter] = BitAND(GUICtrlRead(@GUI_CtrlID), $GUI_UNCHECKED)
                $setPackageState = $GUI_UNCHECKED
            EndIf
            ;Set the appropriate package state if needed.
            If $setPackageState <> 0 Then
                For $packCounter = 1 To $packages[0]
                    $splitPackage = StringSplit($packages[$packCounter], ":")
                    $packageFolder = $splitPackage[1]
                    $packageCat = $splitPackage[2]
                    If $packageCat = $catCounter Then
                        GUICtrlSetState($packElements[$packCounter], $setPackageState)
                    EndIf
                Next
            EndIf
            ExitLoop
        EndIf
    Next
EndFunc

Func packageClicked()
    ;Nothing yet...
    Dim $infoElements, $infoParams, $infoLabels, $packElements, $packages, $packagesInfo
    ;Show all labels showing where label values will go.
    For $labelCounter = 0 To UBound($infoLabels) - 1
        GUICtrlSetState($infoLabels[$labelCounter], $GUI_SHOW)
    Next
    ;Find the selected package and populate the information fields.
    For $packCounter = 1 To $packages[0]
        If @GUI_CtrlID = $packElements[$packCounter] Then
            $packageInfo = StringSplit($packagesInfo[$packCounter], "`")
            For $infoCounter = 1 To UBound($infoElements) - 1
                If $infoElements[$infoCounter] <> 0 Then
                    GUICtrlSetData($infoElements[$infoCounter], $packageInfo[$infoCounter])
                EndIf
            Next
            ExitLoop
        EndIf
    Next
EndFunc

Func beginInstallation()
    ;Find out what, if any, packages were selected and install them.
    Dim $basePath, $categories, $packages, $packElements, $packagesInfo, $optionElements, $actionElements, $progressBar
    GUICtrlSetState($actionElements[1], $GUI_DISABLE)
    GUICtrlSetState($actionElements[2], $GUI_DISABLE)
    Dim $installPacks[1]
    $installPacks[0] = 0
    $systemDrive = EnvGet("systemdrive")
    $localSource = $systemDrive & "\Packages"
    If FileExists($localSource) Then
        If BitAND(GUICtrlRead($optionElements[2]), $GUI_CHECKED) = $GUI_CHECKED Then
            ;Delete the existing local source and create a new one.
            DirRemove($localSource, 1)
            DirCreate($localSource)
        EndIf
    Else
        ;Create a local source folder.
        DirCreate($localSource)
    EndIf
    For $packCounter = 1 To $packages[0]
        If BitAND(GUICtrlRead($packElements[$packCounter]), $GUI_CHECKED) = $GUI_CHECKED Then
            ;The package was selected for installation.
            $packageInfo = StringSplit($packagesInfo[$packCounter], "`")
            $splitPackage = StringSplit($packages[$packCounter], ":")
            $packageFolder = $splitPackage[1]
            $packageCat = $splitPackage[2]
            If BitAND(GUICtrlRead($optionElements[1]), $GUI_CHECKED) = $GUI_CHECKED And $packageInfo[7] = 1 Then
                ;Create a local installation source for the package.
                If Not FileExists($localSource & "\" & $categories[$packageCat] & "\" & $packageFolder) Then
                    DirCreate($localSource & "\" & $categories[$packageCat])
                EndIf
                $relativePath = "\" & $categories[$packageCat] & "\" & $packageFolder
                _FileCopy($basePath & $relativePath, $localSource & "\" & $categories[$packageCat])
                ReDim $installPacks[UBound($installPacks) + 1]
                $installPacks[0] = $installPacks[0] + 1
                $installPacks[$installPacks[0]] = """" & $localSource & $relativePath & "\" & $packageInfo[5] & """" & $packageInfo[6]
            Else
                ;Do not create a local installation source for the package.
                $relativePath = "\" & $categories[$packageCat] & "\" & $packageFolder
                ReDim $installPacks[UBound($installPacks) + 1]
                $installPacks[0] = $installPacks[0] + 1
                $installPacks[$installPacks[0]] = """" & $basePath & $relativePath & "\" & $packageInfo[5] & """" & $packageInfo[6]
            EndIf
        EndIf
    Next
    If $installPacks[0] > 0 Then
        ;_ArrayDisplay($installPacks, "Install List")
        disableZoneChecking()
        If BitAND(GUICtrlRead($optionElements[1]), $GUI_CHECKED) = $GUI_CHECKED And FileExists($localSource) Then
            ;If a local source was created, remove the read-only attribute.
            RunWait("attrib.exe -r " & $localSource & "\* /s /d", "", @SW_HIDE)
            If BitAND(GUICtrlRead($optionElements[3]), $GUI_CHECKED) = $GUI_CHECKED Then
                ;If the user specified to pause after source creation, create a message box to pause the script.
                MsgBox(0, "Pausing", "Local source created.  Please click OK to begin package installation.")
            EndIf
        EndIf
        $progressIncrement = 100 / $installPacks[0]
        $increment = $progressIncrement
        For $installCounter = 1 To $installPacks[0]
            RunWait(@ComSpec & " /c " & $installPacks[$installCounter], "", @SW_HIDE)
            If $installCounter = $installPacks[0] Then
                ;Set the progress bar to 100%.
                GUICtrlSetData($progressBar, 100)
            Else
                ;Increment the progress bar.
                GUICtrlSetData($progressBar, $increment)
                $increment = $increment + $progressIncrement
            EndIf
        Next
        MsgBox(0, "Complete", "Selected packages installed.")
        GUICtrlSetData($progressBar, 0)
        enableZoneChecking()
    EndIf
    GUICtrlSetState($actionElements[1], $GUI_ENABLE)
    GUICtrlSetState($actionElements[2], $GUI_ENABLE)
EndFunc

Func _FileCopy($fromFile, $toFile)
    Local $FOF_RESPOND_YES = 16
    Local $FOF_SIMPLEPROGRESS = 256
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($toFile).CopyHere($fromFile, $FOF_RESPOND_YES)
EndFunc

Func disableZoneChecking()
    ;Disable IE zone checking so security warnings do not appear when installing unsigned packages.
    EnvSet("SEE_MASK_NOZONECHECKS", 1)
EndFunc

Func enableZoneChecking()
    ;Re-enable IE zone checking.
    EnvSet("SEE_MASK_NOZONECHECKS")
EndFunc

Func addSiteToTrustedSites($site)
    ;Add the specified site to the Trusted Sites zone in IE.
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\" & $site, "*", "REG_DWORD", 2)
EndFunc

Func removeSiteFromTrustedSites($site)
    ;Remove the specified site from the Trusted Sites zone in IE.
    RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\" & $site)
EndFunc

Func closeClicked()
    ;Exit the script.
    Exit
EndFunc
Edited by JMiller
Link to comment
Share on other sites

example idea

For $x = 1 to 3
    Call("Test" & $x)
    Sleep(500)
Next

Func Test1()
    MsgBox(4096, "#1", "Hello", 2)
EndFunc

Func Test2()
    MsgBox(4096, "#2", "Hello", 2)
EndFunc

Func Test3()
    MsgBox(4096, "#3", "Hello", 2)
EndFunc

answer to the original question ... without looking through everything

8)

Edited by Valuater

NEWHeader1.png

Link to comment
Share on other sites

  • Moderators

If I'm not mistaken (And now that I think about it I may be)... But I thought Vollyman did something like this a while back.

Edit:

Yeah, it's similar but not quite what your doing, but may give you some ideas, I found it here: http://www.autoitscript.com/forum/index.ph...ndpost&p=145227

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

example idea

For $x = 1 to 3
    Call("Test" & $x)
    Sleep(500)
Next

Func Test1()
    MsgBox(4096, "#1", "Hello", 2)
EndFunc

Func Test2()
    MsgBox(4096, "#2", "Hello", 2)
EndFunc

Func Test3()
    MsgBox(4096, "#3", "Hello", 2)
EndFunc

answer to the original question ... without looking through everything

8)

Thanks for the quick reply. I think I would need to be able to create those functions on the fly... which I'm not sure is possible.
Link to comment
Share on other sites

If I'm not mistaken (And now that I think about it I may be)... But I thought Vollyman did something like this a while back.

Alright, cool. I'll search for his posts. I'm surprised by the quick replies. thank you :)

Edited by JMiller
Link to comment
Share on other sites

  • Moderators

Alright, cool. I'll search for his posts. I'm surprised by the quick replies... thanks :)

Check my edit above, I found the link I thought it may have been.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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