Sign in to follow this  
Followers 0
madmax2

stuck with loops, or need array help

5 posts in this topic

Hi Guys, been using autoit on and off for a year or two doing little small tasks, but this is my first attempt at a proper program.

I've gone through most of the example code forum and nicked bits here and there, but struggling to stitch it together

objective: I have a portable hard drive with a folder full of vista updates, msu files. I would like to run an installer which will create a list of the updates I have on the drive (this bit is sort of working) and then install them one by one.

As said, this is working. code below.

#include <Date.au3>
; searches the current folder for files starting with "windows" and "ms" because microsoft use both.
$searchwindows = FileFindFirstFile("windows*.*") 
$searchms = FileFindFirstFile("ms*.*")
$echo1= 0; define the echo variable, used as a counter
 $file = FileFindNextFile($searchwindows); go and find the file
  If @error Then; oh no, no file
      MsgBox(4096, "INFO" , "No files to install, Exiting in 10 seconds", 10); make a message pop on screen,  autoclose after 10 seconds
      exit; kill me
  else; or....
      $echo1=$echo1+1; increase the counter by 1
 msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); make a 10 second message box, containing filename and counter info
ShellExecuteWait($file, " /quiet /norestart"); actually install the file
endif; end of the if's

 While 1; awaiting...
    $file = FileFindNextFile($searchwindows); carry on looking for the next "windows" file 
    If @error Then ExitLoop; none found? exit
$echo1=$echo1+1; found one? increase counter
msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); pop up 10 second message box, filename and counter info
    shellexecutewait($file, " /quiet /norestart"); install this file
WEnd; awaiting..

while 1; awaiting
 $file = FileFindNextFile($searchms); lets start looking for the "ms" files 
 If @error Then ExitLoop; none found, exit the program
 $echo1=$echo1+1; found one? increase the counter
 msgbox(4096, "info" , "INSTALLING " & $file & $echo1,  10); 10 second message box, filename and counter info
shellexecutewait($file, " /quiet /norestart"); actually install the file
 wend; awaiting..
 

FileClose($searchwindows); end your search for windows
fileclose($searchms); end your search for ms
; dodgy bit follows, writing the date to csup.txt
fileopen("C:\windows\csup.txt", 2); open the file for writing, overwriting previous contents
FileWrite("c:\windows\csup.txt",@mon); grab month info
filewrite("C:\windows\csup.txt", "-"); stick a - in the file
filewrite("C:\windows\csup.txt", @MDAY); grab the day info
filewrite("C:\windows\csup.txt", "-"); stick a - in the file
filewrite("C:\windows\csup.txt", @YEAR); grab year info
FileClose("C:\windows\csup.txt"); finish writing the file

If FileExists("c:\windows\csup.txt") Then; if csup.txt exists
   MsgBox(4096, "CSUP File", "CSUP.TXT Exists. All OK!", 10); show a 10 second success messagebox
Else; otherwise
    MsgBox(4096,"CSUP ERROR", "CSUP Does NOT exist!!!!!"); show a message box with error info, user must click on it
EndIf; finish the if's
msgbox(0, "COMPLETE", "Installation complete, please reboot"); all complete, show a messagebox, user must click
     Exit; end this sucka

I now want to expand on this, and have the installer check the registry to see if the update is already installed, if it is, skip that one and check the next filename. Here is where I am failing.

my new code (the actuall shellexecutewait line is disabled while i am testing, i just try to update a counter instead and display it at the end to see what it would have done

#include <Date.au3>
; searches the current folder for files starting with "windows" and "ms"
$searchwindows = FileFindFirstFile("windows*.*") 
$searchms = FileFindFirstFile("ms*.*")
$echo1= 0; define the echo variable, used as a counter
$testvalue=0 
 $file = FileFindNextFile($searchwindows); go and find the file
  If @error Then; oh no, no file
      MsgBox(4096, "INFO" , "No files to install, Exiting in 10 seconds", 10); make a message pop on screen,  autoclose after 10 seconds
      exit; kill me
  else; or....
      $echo1=$echo1+1; increase the counter by 1
;comparison_test
endif
$test=$file
For $i= 1 to 200
    $var = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages", $i)
    If @error <> 0 then ExitLoop
$result= StringInStr($var, $test,2) 
if $result = 0 Then
    $result=$result
    Else
     msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); make a 10 second message box, containing filename and counter info
;ShellExecuteWait($file, " /quiet /norestart"); actually install the file
$testvalue=$testvalue+1
endif; end of the if's
Next
 While 1; awaiting...
    $file = FileFindNextFile($searchwindows); carry on looking for the next "windows" file 
    If @error Then ExitLoop; none found? exit
$echo1=$echo1+1; found one? increase counter
;comparison_test
$test=$file
For $i= 1 to 200
    $var = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages", $i)
    If @error <> 0 then ExitLoop
$result= StringInStr($var, $test,2) 
if $result = 0 Then
    $result=$result
    Else
     msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); make a 10 second message box, containing filename and counter info
;ShellExecuteWait($file, " /quiet /norestart"); actually install the file
$testvalue=$testvalue+1
EndIf   
next
WEnd; awaiting..

while 1; awaiting
 $file = FileFindNextFile($searchms); lets start looking for the "ms" files 
 If @error Then ExitLoop; none found, exit the program
 $echo1=$echo1+1; found one? increase the counter
;comparison_test
$test=$file
For $i= 1 to 200
    $var = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages", $i)
    If @error <> 0 then ExitLoop
$result= StringInStr($var, $test,2) 
if $result = 0 Then
    $result=$result
    Else
     msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); make a 10 second message box, containing filename and counter info
;ShellExecuteWait($file, " /quiet /norestart"); actually install the file
$testvalue=$testvalue+1
EndIf   
next
 wend; awaiting..
FileClose($searchwindows); end your search for windows
fileclose($searchms); end your search for ms
; dodgy bit follows, writing the date to csup.txt
fileopen("C:\windows\csup.txt", 2); open the file for writing, overwriting previous contents
FileWrite("c:\windows\csup.txt",@mon); grab month info
filewrite("C:\windows\csup.txt", "-"); stick a - in the file
filewrite("C:\windows\csup.txt", @MDAY); grab the day info
filewrite("C:\windows\csup.txt", "-"); stick a - in the file
filewrite("C:\windows\csup.txt", @YEAR); grab year info
FileClose("C:\windows\csup.txt"); finish writing the file

If FileExists("c:\windows\csup.txt") Then; if csup.txt exists
   MsgBox(4096, "CSUP File", "CSUP.TXT Exists. All OK!", 10); show a 10 second success messagebox
Else; otherwise
    MsgBox(4096,"CSUP ERROR", "CSUP Does NOT exist!!!!!"); show a message box with error info, user must click on it
EndIf; finish the if's
msgbox(0, "COMPLETE", "Installation complete, please reboot"); all complete, show a messagebox, user must click
     
     msgbox(0, "updates installed", $testvalue)
     
     Exit; end this sucka

I realise this is a long first post, but I have really been trying hard to get this sorted, but right now I am so lost I cant even understand my own code and figure out what I was thinking.

It has been suggested to use an array, but obviously I am a bit green on those. I have put some sample bits in and gotten the updates avauilable to be installed into an array, but I do not know how to query this against the registry keys

any help would be most welcome

Madmax2

Share this post


Link to post
Share on other sites



If you have some time for it you could try this array tutorial. People have found it to be handy before. if you find any issues with it please let me know so we can get it updated.

Share this post


Link to post
Share on other sites

If you have some time for it you could try this array tutorial. People have found it to be handy before. if you find any issues with it please let me know so we can get it updated.

i read that on sunday night when i first had the idea that maybe an array was better than a loop, but i just dont have the talent to actually put two and two together.

for example, if my simple array contained text data

KB123456

KB132478

KB678387

what method would i then use to check this against a registry key, one by one?

or, if my array contained all the registry keys, and array (column of same array?) contained the kb numbers, how would i do a compare?

Share this post


Link to post
Share on other sites

i read that on sunday night when i first had the idea that maybe an array was better than a loop, but i just dont have the talent to actually put two and two together.

for example, if my simple array contained text data

KB123456

KB132478

KB678387

what method would i then use to check this against a registry key, one by one?

or, if my array contained all the registry keys, and array (column of same array?) contained the kb numbers, how would i do a compare?

It's not a choice between an array OR a loop. Arrays are just easier to loop through. For instance if the KB's were listed in an array called $avKBs you could loop like this:

For $k = 0 To UBound($avKBs) - 1
    _CheckRegistryKB($avKBs[$k])
Next

Func _CheckRegistryKB($sKB)
    MsgBox(64, "KB Reg", "Checking " & $sKB & " in the registry...")
    ; Stuff to check the registry
    ; $sKB = string of KB (i.e. "KB123456")
EndFunc

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Just keep on :) madmax2, you will get it right eventually..;)

Your task has many small tasks. NOTE! I have not read your code, so if this sounds offensive please forgive me.

1: Read all the file names

2: Compare against already installed sp/kb files

3: Consider i the file should be installed at all (if some feature ain't installed on the computer you don't have to/should not install the sp/kb)?

4: Sort all the files to be installed. This could be done after you have decided to include the file or as you read the file name.

5: Install the file.

6: Error checking and handling.

7: Do we have to consider a restart and then continue the process?

8: Write a report (and mail it?)?

As @PsaltyDS pointed out using arrays does not exclude anything.

Your task is easier if you know how to use arrays. Actually array's are the only native option in AutoIt to store and handle large quantities of data entries.

Each step I listed above could be made as a function. Actually you should break down the code you have provided into functions.

Take a look at this refactoring suggestion of your code:

#include <Date.au3>
Local $arrSortedFiles[100];Space fro 99 filenames + a position. 
Local $arrSortedFiles[0] = 0; Use the first entry as a position indicator
FindSpKbFiles($arrSortedFiles, "winddow*.*")
FindSpKbFiles($arrSortedFiles, "ms*.*")
InstallSpKbs($arrSortedFiles)
WriteCSUPLog()

Func AddSpKbToSortedList(ByRef $arr, $data, $sortall=0)
  ;Routine to sort and add data to the array
  ;NOTE! The forum have several samples of how to do this.
  ; You will probably find functions in the Array.au3 UDF to.
  ; $sortall indicates if the array is to be consider presorted.
  ; If $sortall is 1 we should check the entier array.
  ;1: Make sure the array is big enough
  ;2: Make sure it is sorted
EndFunc
Func InstallSpKbs(ByRef $arr)
;Installation routine.
;This need some error handeling
; So you should probably make a loop in this function and use a InstallSpKb to do the actuall installation
    For $i = 1 to $arr[0]
        If not InstallSpKb($arr[$i]) Then 
    ; NOTE! Log error?
        EndIf
    Next
EndFunc
Func InstallSpKb($SpKbPathName)
;NOTE! TODO:
EndFunc
Func FindSpKbFiles(ByRef $arrSortedFiles, $FilePattern)
; searches the current folder for files starting with "windows" and "ms"
    $searchwindows = FileFindFirstFile($FilePattern)
    $echo1= 0; define the echo variable, used as a counter
    $testvalue=0
    While 1; awaiting...
        $file = FileFindNextFile($searchwindows); carry on looking for the next "windows" file
        If @error Then ExitLoop; none found? exit
        $echo1=$echo1+1; found one? increase counter
;comparison_test
        If Not IsSpKbInstalled($file) Then 
            AddSpKbToSortedList($arrSortedFiles, $file)
        EndIf

    WEnd; awaiting..
    FileClose($searchwindows); end your search for windows
EndFunc
Func IsSpKbInstalled($test)
    For $i= 1 to 200
        $var = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages", $i)
        If @error <> 0 then ExitLoop
;NOTE! This test, does it work?
        $result= StringInStr($var, $test,2)
        if $result = 0 Then
            $result=$result
            Else
             msgbox(4096, "info" , "INSTALLING " & $file & $echo1, 10); make a 10 second message box, containing filename and counter info
;ShellExecuteWait($file, " /quiet /norestart"); actually install the file
        $testvalue=$testvalue+1
        endif; end of the if's
    Next
;NOTE! Make it return true or false
    Return $testvalue
EndFunc


Func WriteCSUPLog()
; dodgy bit follows, writing the date to csup.txt
    fileopen("C:\windows\csup.txt", 2); open the file for writing, overwriting previous contents
    FileWrite("c:\windows\csup.txt",@mon); grab month info
    filewrite("C:\windows\csup.txt", "-"); stick a - in the file
    filewrite("C:\windows\csup.txt", @MDAY); grab the day info
    filewrite("C:\windows\csup.txt", "-"); stick a - in the file
    filewrite("C:\windows\csup.txt", @YEAR); grab year info
    FileClose("C:\windows\csup.txt"); finish writing the file

    If FileExists("c:\windows\csup.txt") Then; if csup.txt exists
       MsgBox(4096, "CSUP File", "CSUP.TXT Exists. All OK!", 10); show a 10 second success messagebox
    Else; otherwise
        MsgBox(4096,"CSUP ERROR", "CSUP Does NOT exist!!!!!"); show a message box with error info, user must click on it
    EndIf; finish the if's
    msgbox(0, "COMPLETE", "Installation complete, please reboot"); all complete, show a messagebox, user must click
        
    msgbox(0, "updates installed", $testvalue)
EndFunc

This code is untested by me. I have just broken your code down to try to show you a better approach (at least that is my opinion.;) ).

Happy Scripting

Edited by Uten

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