JMiller Posted May 21, 2006 Share Posted May 21, 2006 (edited) 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: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 applicationHere is the code I have so far.expandcollapse popup;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 June 2, 2006 by JMiller Link to comment Share on other sites More sharing options...
Valuater Posted May 21, 2006 Share Posted May 21, 2006 (edited) 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 May 21, 2006 by Valuater Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted May 21, 2006 Moderators Share Posted May 21, 2006 (edited) 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 May 21, 2006 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 More sharing options...
JMiller Posted May 21, 2006 Author Share Posted May 21, 2006 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 More sharing options...
JMiller Posted May 21, 2006 Author Share Posted May 21, 2006 (edited) 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 May 21, 2006 by JMiller Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted May 21, 2006 Moderators Share Posted May 21, 2006 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 More sharing options...
JMiller Posted May 21, 2006 Author Share Posted May 21, 2006 Check my edit above, I found the link I thought it may have been.Wow it's almost the same exact idea but a lot more thoroughly developed. I'll dig through the code for ideas. Thanks again. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now