Jump to content

Populating Array of Unknown Size


Recommended Posts

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
Link to comment
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 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
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

Link to comment
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.

Link to comment
Share on other sites

  • Moderators

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

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see 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

 

Link to comment
Share on other sites

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
Link to comment
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
Link to comment
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.

Link to comment
Share on other sites

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...