Sign in to follow this  
Followers 0
Neejay

Reading from Array AND have progress bar

8 posts in this topic

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

 

Share this post


Link to post
Share on other sites



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]) )

:)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Right but inconsequential (assuming it's a 'work in progress'), this assignation is done in the func but not used  :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

#6 ·  Posted (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 by mikell
1 person likes this

Share this post


Link to post
Share on other sites

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.

#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

Share this post


Link to post
Share on other sites

#8 ·  Posted (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 by mikell

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  
Followers 0