Jump to content
Sign in to follow this  
Neejay

Reading from Array AND have progress bar

Recommended Posts

Neejay
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
mikell

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
MilesAhead

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
mikell

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
Neejay
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
mikell

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
  • Like 1

Share this post


Link to post
Share on other sites
Neejay

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
mikell

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.