Sign in to follow this  
Followers 0
DarkDeveloper

Populating Array of Unknown Size

9 posts in this topic

This is what I have so far and it works. I wasn't sure if there is a better way to do this. Next step is going to be getting display name and uninstall key. I just wanted to make sure that this is a good way to do the task I am attempting before continuing.

Func _uninstallProgram()

;reg to start at
Local $regamount = 1

;get the number of reg

While RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $regamount)

$regamount += 1



WEnd

;View error while loop stops on, should be -1 if all reg counted
MsgBox(0,"","Array Size: " & $regamount & " Error: " & @error)

;declare array size
Local $array[$regamount]

;populate array with list of reg names
For $i=0 to $regamount - 1

$array[$i] = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $i)

Next

;check that list populated
_ArrayDisplay($array)

EndFunc

Share this post


Link to post
Share on other sites



If it works and it is fast enough then you are fine.

If it is too slow we can show you how to speed up the code.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

You can use _ArrayAdd() so you dont have to enumerate the registry two times. This might be a bit slow for large amounts of data, since the array is resized every time - you could maybe modify the function so the array grows by, say, 1.3 * size when full.


Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

There is only 400ish registries per computer. It will grow as more MS updates come but shouldn't be too bad. I do see what you mean Shaggi. I'll tweak with the logic a bit. The first one is just to get the number of registries that exist so I can declare an array size. I'll play around with some other things and if it slows down I will let you know.

Share this post


Link to post
Share on other sites

DarkDeveloper,

Take a look at the final script (and following explanation) in the Recursion tutorial in the Wiki - it shows how you can fill an array of unknown size with the minimum number of ReDim calls. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Memory is nothing anymore...

Just set a large array up front and Redim() it once at the end (which frees the unneeded memory).

Throw in an error message in case anyone ever gets close to overflowing the table.

#include <Array.au3>
Global $iMaxArray = 2500, $array[$iMaxArray + 1]
_uninstallProgram()
_ArrayDisplay($array)

Func _uninstallProgram()
For $i = 1 to $iMaxArray
     $array[$i] = RegEnumKey("HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall", $i)
     If @error Then ExitLoop
Next
If $i > $iMaxArray Then
     MsgBox(16, "Error", "Maximum table size exceeded.")
Exit
EndIf
$array[0] = $i - 1
ReDim $array[$i]
EndFunc

Edit: Realistically, you could preset the array to a million elements and it might temporary allocate 20MB of memory until it hits the ReDim() and frees it up. For a wimpy PC with just a measly 1GB that's still only a temporary allocation of 2% of it's memory. Presetting it to anywhere from 1000 to 5000 won't even cause a PC to skip a beat.

Edited by Spiff59

Share this post


Link to post
Share on other sites

I looked at the recursion page but I don't think it will work since I cannot check for a next registry. However I did do this instead which works and should be more friendly to the part I am doing next.

Func _uninstallProgram($programName)

Local $array[20]

$array[0] = UBound($array,1)

MsgBox(0,"",$array[0])

$i = 1

Do

$array[$i] = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $i)

If StringCompare ($array[$i], "") = 0 Then

MsgBox(0,"","Blank Spot at " & $i)

ReDim $array[$i]

ExitLoop

ElseIf $i = $array[0]-1 Then

ReDim $array[UBound($array,1) * 2]

$array[0] = UBound($array,1)

MsgBox(0,"",$array[0])

EndIf

$i += 1

Until $i >= $array[0]

ReDim $array[UBound($array,1)]



MsgBox(0,"",@error)

_ArrayDisplay($array)

EndFunc

Share this post


Link to post
Share on other sites

Check out my topic (I actually just posted this), that has a #include that you can use for a stack data structure. It'll work pretty well, and after you're done using it, you can just call a function and it will return an array for you to use.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Idk if this is a stupid idea, but you could just store all the values in a string and separate them with a character, say "|", then use stringsplit? (this way it would automatically size the array, and only have to enum once)

Local $regamount = 1
Local $keys = ''
do
$key = RegEnumKey("HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall", $regamount)
$keys &= $key&'|'
$regamount += 1
until @error
$array = stringsplit($keys, '|')

Edit: working example

Edited by nullschritt
1 person likes this

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