Neejay Posted April 28, 2014 Share Posted April 28, 2014 I'm trying to do an array with specified MS patches, and while performing my _Patch() function, have a progress bar as well. I can get ArrayDisplay to list the MS patches I want to install, but it seems to only do a count (MS1, MS2, MS3...MS11) then exits. It doesn't actually run through my _Patch() function. The progress bar appears to correctly do the math, but it also only gets to 66%, just like the count stops at MS11: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=..\scripts\x86_TEST_2.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <file.au3> #include <array.au3> #include <Misc.au3> #include <ProgressConstants.au3> #include <Constants.au3> #include <MsgBoxConstants.au3> Local $iPercentage Local $Patches = @ScriptDir & "\..\Patches\W7\" ; Path must have the trailing \ ;Local $KB_Name ;Local $iCurrentItem = $KB_Name ;Local $aNumbers = UBound($aPatches) $aHotFixList = _GetHotFixes() ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iPercentage = ' & $iPercentage & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console Global $aPatches[] = ["11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-037-KB2544893", "11-043-KB2536276", "11-048-KB2536275", "11-053-KB2532531", "11-071-KB2570947", "11-092-KB2619339", "12-004-KB2631813", "12-013-KB2654428", "12-020-KB2667402", "12-024-KB2653956"] _ArrayDisplay($aPatches) $iNumberOfItems = 15 ProgressOn("W7 Patch Installation", "Completion:", "0 percent completed.", "", "", 16) For $iCurrentItem = 1 To $aPatches[0] ;_FileReadToArray(@ScriptDir & "\..\Patches\patches.txt", $aPatches) _Patch($iCurrentItem) Local $iPercentage = Int(($iCurrentItem / $iNumberOfItems) * 100) ProgressSet($iPercentage, $iPercentage & "% completed") Next ProgressSet(100, " Done!", " Complete") ProgressOff() Func _Patch($KB_Name) $iCurrentItem = $KB_Name $KB_Number = StringMid($KB_Name, 8, 9) _ArraySearch($aHotFixList, $KB_Number) If @error <> 0 Then $inst = Run(@ComSpec & " /c " & $Patches & $KB_Name & ".msu /quiet /norestart", "", @SW_HIDE) If @error Then $inst = Run(@ComSpec & " /c " & $Patches & $KB_Name & ".exe /quiet /norestart", "", @SW_HIDE) EndIf While ProcessExists($inst) TrayTip("Installing " & "MS" & StringLeft($KB_Name, 6), "Please be patient.", 5) Sleep(250) WEnd TrayTip("x", "", 0) ;_FileWriteLog($Timelog, "Installed MS" & $KB_Name) EndIf EndFunc ;==>_Patch Func _GetHotFixes() Local $oColItems, $oWMIService, $sOutput $oWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") $oColItems = $oWMIService.ExecQuery("Select HotFixID From Win32_QuickFixEngineering", "WQL", 0x30) For $oItem In $oColItems $sOutput &= $oItem.HotFixID & ";" Next Return StringSplit(StringTrimRight($sOutput, 1), ";") EndFunc ;==>_GetHotFixes Some help would be greatly appreciated! Thanks in advance. Link to comment Share on other sites More sharing options...
mikell Posted April 28, 2014 Share Posted April 28, 2014 Global $aPatches[] = ["11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-037-KB2544893", "11-043-KB2536276", "11-048-KB2536275", "11-053-KB2532531", "11-071-KB2570947", "11-092-KB2619339", "12-004-KB2631813", "12-013-KB2654428", "12-020-KB2667402", "12-024-KB2653956"] Msgbox(0,"", Number($aPatches[0]) ) Link to comment Share on other sites More sharing options...
MilesAhead Posted April 28, 2014 Share Posted April 28, 2014 In addition to mikell's putting his finger on the main bug, I don't get what you do with $iCurrentItem. You seem to want it Local but you access it inside the function and pass its value to itself. Just use the passed param instead of assigning it. My Freeware Page Link to comment Share on other sites More sharing options...
mikell Posted April 28, 2014 Share Posted April 28, 2014 Right but inconsequential (assuming it's a 'work in progress'), this assignation is done in the func but not used Link to comment Share on other sites More sharing options...
Neejay Posted April 28, 2014 Author Share Posted April 28, 2014 Global $aPatches[] = ["11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-024-KB2491683", "11-024-KB2506212", "11-030-KB2509553", "11-037-KB2544893", "11-043-KB2536276", "11-048-KB2536275", "11-053-KB2532531", "11-071-KB2570947", "11-092-KB2619339", "12-004-KB2631813", "12-013-KB2654428", "12-020-KB2667402", "12-024-KB2653956"] Msgbox(0,"", Number($aPatches[0]) ) hmm...I'm getting 11. Does that mean the that dash in the array name isn't taken into account and breaks the array list? It appears to be 11 for any $aPatches number... In addition to mikell's putting his finger on the main bug, I don't get what you do with $iCurrentItem. You seem to want it Local but you access it inside the function and pass its value to itself. Just use the passed param instead of assigning it. Sorry it's a bit of a mess. I've been trying so many things, I think I've screwed up the code even worse. I'm trying to get $iCurrentItem to match the KB Name of the Patch and that name is what gets passed into the function to actually patch....if that makes sense. Right but inconsequential (assuming it's a 'work in progress'), this assignation is done in the func but not used Definitely a work in progress. Link to comment Share on other sites More sharing options...
mikell Posted April 28, 2014 Share Posted April 28, 2014 (edited) Sorry for not being explicit enough The purpose was to highlight the weirdness in the For loop For $iCurrentItem = 1 To $aPatches[0] This means : from 1 to 11, because $aPatches[0] contains an update reference, not the number of updates which is 15 The correct way should be For $iCurrentItem = 0 To UBound($aPatches)-1 ; from 0 to 14, looping through the array ; or ; For $iCurrentItem = 0 To $iNumberOfItems-1 _Patch($Patches[$iCurrentItem]) ; so $KB_Name in the func will really be an update name Local $iPercentage = Int(($iCurrentItem+1 / $iNumberOfItems) * 100) ; note the "+1" ProgressSet($iPercentage, $iPercentage & "% completed") Next Note that you can also do it like this : Global $aPatches[] = ["15", "11-024-KB2491683", "11-024-KB2506212", ... etc ] For $iCurrentItem = 1 To $aPatches[0] ; this will work because $aPatches[0] = 15 ; etc Edited April 28, 2014 by mikell Neejay 1 Link to comment Share on other sites More sharing options...
Neejay Posted May 1, 2014 Author Share Posted May 1, 2014 Mikell, thanks a lot!! I had to put an extra set of parenthesis around "$iCurrentItem + 1" to calculate correctly, but the actual progress bar and patching finally works. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=..\scripts\x86_TEST_3.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <file.au3> #include <array.au3> #include <Misc.au3> #include <ProgressConstants.au3> #include <Constants.au3> #include <MsgBoxConstants.au3> Local $iPercentage, $KB_Name, $aPatches = 0, $aNet = 0, $iPercentage, $iNumberOfItems Local $Patches = @ScriptDir & "\..\Patches\W7\" ; Path must have the trailing \ $aHotFixList = _GetHotFixes() $iNumberOfItems = 80 If Not _FileReadToArray(@ScriptDir & "\..\Patches\W7\patches.txt", $aPatches, 0) Then MsgBox($MB_SYSTEMMODAL, "", "There was an error reading the file. @error: " & @error) EndIf _ArrayDisplay($aPatches) If Not _FileReadToArray(@ScriptDir & "\..\Patches\W7\net.txt", $aNet, 0) Then MsgBox($MB_SYSTEMMODAL, "", "There was an error reading the file. @error: " & @error) EndIf _ArrayDisplay($aNet) ProgressOn("W7 Patch Installation", "Completion:", "0 percent completed.", "", "", 16) For $iCurrentItem = 0 To UBound($aPatches)-1 ; loops _Patch($aPatches[$iCurrentItem]) ; names $KB_Name properly Local $iPercentage = Int((($iCurrentItem + 1) / $iNumberOfItems) * 100) ; note the "+1" ProgressSet($iPercentage, $iPercentage & "% completed") Next For $iCurrentItem = 0 To UBound($aNet)-1 ; loops If Not _NetInstalled($aNet) Then _Patch($aNet[$iCurrentItem]) ;.NET EndIf Local $iPercentage = Int((($iCurrentItem + 1) / $iNumberOfItems) * 100) ; note the "+1" ProgressSet($iPercentage, $iPercentage & "% completed") Next ProgressSet(100, " Done!", " Complete") ProgressOff() Func _Patch($KB_Name) $KB_Number = StringMid($KB_Name, 8, 9) _ArraySearch($aHotFixList, $KB_Number) If @error <> 0 Then $inst = Run(@ComSpec & " /c " & $Patches & $KB_Name & ".msu /quiet /norestart", "", @SW_HIDE) If @error Then $inst = Run(@ComSpec & " /c " & $Patches & $KB_Name & ".exe /quiet /norestart", "", @SW_HIDE) EndIf While ProcessExists($inst) TrayTip("Installing " & "MS" & StringLeft($KB_Name, 6), "Please be patient.", 5) Sleep(250) WEnd TrayTip("x", "", 0) ;_FileWriteLog($Timelog, "Installed MS" & $KB_Name) EndIf EndFunc ;==>_Patch Func _GetHotFixes() Local $oColItems, $oWMIService, $sOutput $oWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") $oColItems = $oWMIService.ExecQuery("Select HotFixID From Win32_QuickFixEngineering", "WQL", 0x30) For $oItem In $oColItems $sOutput &= $oItem.HotFixID & ";" Next Return StringSplit(StringTrimRight($sOutput, 1), ";") EndFunc ;==>_GetHotFixes Func _NetInstalled($NETKB) $GUID = StringMid($NETKB, 8, 9) $Uninstall = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{3C3901C5-3455-3E0A-A214-0B093A5070A6}." & $GUID, "DisplayVersion") If @error Then Return False Else Return True EndIf EndFunc ;==>NetInstalled I decided to throw them into text files. Now, Im trying different code to figure out how to merge the progress bar progress with other functions/loops. As it sits now, I can only create separate progress bars, but not a single "parent" one Link to comment Share on other sites More sharing options...
mikell Posted May 1, 2014 Share Posted May 1, 2014 (edited) Creating a single progressbar requires a simple proration for the value to set Here is a very simple example with 3 loops but you can easily imagine something similar using funcs instead of the loops ProgressOn("Progress", "", "0%") $val1 = 15 $val2 = 50 Global $total = 0 For $i = 1 To $val1 $total += 1 Sleep(200) ProgressSet($total, "total : " & $total & "%", "loop 1 : " & $i & "%") Next For $i = 1 To $val2 $total += 1 Sleep(200) ProgressSet($total, "total : " & $total & "%", "loop 2 : " & $i & "%") Next For $i = 1 To 100-$total ; 100-($val1+$val2) $total += 1 Sleep(200) ProgressSet($total, "total : " & $total & "%", "loop 3 : " & $i & "%") Next ProgressSet(100, "Done", "Complete") Sleep(3000) ProgressOff() Edited May 1, 2014 by mikell 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