petesa Posted April 7, 2007 Share Posted April 7, 2007 Any help is really appreciated... I am trying to write an AutoIt script that can search the uninstall area of the registry for a keyword (i.e. part of program name without need for the name of the exact registry entry) and then automatically uninstall all found programs. Eventually I wanted to be able to provide the keyword to the compiled script via command line parameter. The bad news is that I am just a beginner I am not sure if the approach that I am taking makes sense. The "sticking point" seems to be with arrays; I am attempting to build a new set of arrays based on a previous array and I am getting a "Array variable has incorrect number of subscripts or subscript dimension range exceeded.:" error. Thank you in advance expandcollapse popupOpt("MustDeclareVars", 1) Local $a_DispName[10], $a_NameOfProg[10], $a_GetUninstallRunLine[10] Global $DisplayName = 1, $NameOfProg = 1, $GetUninstallRunLine = 0, $UninstallRunLine = 0 _Main() Func _Main() Local $a_subkeys = _RegEnumKeys(".", "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"), $x, $y, $a_keys If Not @error Then For $x = 0 To UBound($a_subkeys) - 1 _DebugPrint($a_subkeys[$x]) $a_keys = _RegEnumValues(".", "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $a_subkeys[$x]) If Not @error Then For $y = 0 To UBound($a_keys) - 1 ConsoleWrite($a_keys[$y][0] & @TAB & ":" & @TAB & $a_keys[$y][1] & @TAB & ":" & @TAB & $a_keys[$y][2] & @LF) $DisplayName = StringInStr($a_keys[$y][0], "DisplayName") If $DisplayName <> 0 Then ;Find application name in uninstall area in registry $NameOfProg = StringInStr($a_keys[$y][1], "AutoIt") If $NameOfProg <> 0 Then $GetUninstallRunLine = 1 For $w = 0 To UBound($a_DispName, 1) - 1 ;Issue 1 how to get array data into new array for use in uninstall loop to uninstall multiple programs? $a_DispName[$w] = ($a_keys[$y][0]) Next For $v = 0 To UBound($a_NameOfProg, 1) - 1 $a_NameOfProg[$v]= ($a_keys[$y][1]) Next EndIf EndIf $UninstallRunLine = StringInStr($a_keys[$y][0], "UninstallString") If $UninstallRunLine <> 0 Then If $GetUninstallRunLine = 1 Then ;Issue 2 MsgBox(0, "TEST", $a_DispName[$w], 10) For $u = 0 To UBound($a_GetUninstallRunLine, 1) - 1 $a_GetUninstallRunLine[$u] = ($a_keys[$y][1]) Next $GetUninstallRunLine = 0 EndIf EndIf Next EndIf Next EndIf EndFunc ;==>_Main ;Dim $sArrayString = _ArrayToString($MyArray, @TAB, 1, 7) ;MsgBox(4096, "_ArrayToString() Test", $sArrayString) ;~ Func _Main() ;~ Local $a_subkeys = _RegEnumKeys(".", "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion"), $x, $y, $a_keys ;~ If Not @error Then ;~ For $x = 0 To UBound($a_subkeys) - 1 ;~ _DebugPrint($a_subkeys[$x]) ;~ $a_keys = _RegEnumValues(".", "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\" & $a_subkeys[$x]) ;~ If Not @error Then ;~ For $y = 0 To UBound($a_keys) - 1 ;~ ConsoleWrite($a_keys[$y][0] & @TAB & ":" & @TAB & $a_keys[$y][1] & @TAB & ":" & @TAB & $a_keys[$y][2] & @LF) ;~ Next ;~ EndIf ;~ Next ;~ EndIf ;~ EndFunc ;==>_Main ;=============================================================================== ; ; Description: _RegEnumValues ; Parameter(s): computer name - string of remote computer or "." for current computer ; registry tree - contains the sSubKeyName path ; sub key name - A path that contains the named values to be enumerated ; Requirement: None ; Return Value(s): Returns a multi-dimensional array ([0] = key name, [1] = key value, [2] = key type) ; If an error occurs @error is set and 0 is returned ; User CallTip: _RegEnumValues(computer name, registry tree, sub key name) Enumerates the values of the given subkey ; Author(s): Gary Frost (custompcs at charter dot net) ; Note(s): A registry tree can be one of: ; "HKEY_LOCAL_MACHINE" ("HKLM") ; "HKEY_USERS" ("HKU") ; "HKEY_CURRENT_USER" ("HKCU") ; "HKEY_CLASSES_ROOT" ("HKCR") ; "HKEY_CURRENT_CONFIG" ("HKCC") ; ;=============================================================================== Func _RegEnumValues($strComputer, $s_hDefKey, $strKeyPath) Local $hDefKey, $x Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG If $strComputer = "." Then $strComputer = @ComputerName Switch StringUpper($s_hDefKey) Case "HKEY_LOCAL_MACHINE", "HKLM" $hDefKey = $HKEY_LOCAL_MACHINE Case "HKEY_USERS", "HKU" $hDefKey = $HKEY_USERS Case "HKEY_CURRENT_USER", "HKCU" $hDefKey = $HKEY_CURRENT_USER Case "HKEY_CLASSES_ROOT", "HKCR" $hDefKey = $HKEY_CLASSES_ROOT Case "HKEY_CURRENT_CONFIG", "HKCC" $hDefKey = $HKEY_CURRENT_CONFIG Case Else Return SetError(1, 1, 0) EndSwitch Local $a_Type[8] = [7, "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", "", "", "REG_MULTI_SZ"] Local $arrValueNames, $arrValueTypes Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv") $oReg.EnumValues ($HKEY_LOCAL_MACHINE, $strKeyPath, $arrValueNames, $arrValueTypes) If Not IsArray($arrValueNames) Then Return SetError(2, 2, 0) Local $a_ret[UBound($arrValueNames) ][3] For $x = 0 To UBound($arrValueNames) - 1 $a_ret[$x][0] = $arrValueNames[$x] $a_ret[$x][1] = RegRead($s_hDefKey & "\" & $strKeyPath, $arrValueNames[$x]) $a_ret[$x][2] = $a_Type[$arrValueTypes[$x]] Next Return $a_ret EndFunc ;==>_RegEnumValues ;=============================================================================== ; ; Description: _RegEnumKeys ; Parameter(s): computer name - string of remote computer or "." for current computer ; registry tree - contains the sSubKeyName path ; sub key name - A path that contains the named values to be enumerated ; Requirement: None ; Return Value(s): Returns An array of subkey strings ; If an error occurs @error is set and 0 is returned ; User CallTip: _RegEnumKeys(computer name, registry tree, sub key name) Enumerates the subkeys for a path ; Author(s): Gary Frost (custompcs at charter dot net) ; Note(s): A registry tree can be one of: ; "HKEY_LOCAL_MACHINE" ("HKLM") ; "HKEY_USERS" ("HKU") ; "HKEY_CURRENT_USER" ("HKCU") ; "HKEY_CLASSES_ROOT" ("HKCR") ; "HKEY_CURRENT_CONFIG" ("HKCC") ; ;=============================================================================== Func _RegEnumKeys($strComputer, $s_hDefKey, $strKeyPath) Local $hDefKey, $x Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG If $strComputer = "." Then $strComputer = @ComputerName Switch StringUpper($s_hDefKey) Case "HKEY_LOCAL_MACHINE", "HKLM" $hDefKey = $HKEY_LOCAL_MACHINE Case "HKEY_USERS", "HKU" $hDefKey = $HKEY_USERS Case "HKEY_CURRENT_USER", "HKCU" $hDefKey = $HKEY_CURRENT_USER Case "HKEY_CLASSES_ROOT", "HKCR" $hDefKey = $HKEY_CLASSES_ROOT Case "HKEY_CURRENT_CONFIG", "HKCC" $hDefKey = $HKEY_CURRENT_CONFIG Case Else Return SetError(1, 1, 0) EndSwitch Local $a_Type[8] = [7, "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", "", "", "REG_MULTI_SZ"] Local $arrValueNames, $arrValueTypes Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv") $oReg.EnumKey ($HKEY_LOCAL_MACHINE, $strKeyPath, $arrValueNames) If Not IsArray($arrValueNames) Then Return SetError(2, 2, 0) Return $arrValueNames EndFunc ;==>_RegEnumKeys Func _DebugPrint($s_text) $s_text = StringReplace($s_text, @LF, @LF & "-->") ConsoleWrite("!===========================================================" & @LF & _ "!===========================================================" & @LF & _ "-->" & $s_text & @LF & _ "!===========================================================" & @LF) EndFunc ;==>_DebugPrint Link to comment Share on other sites More sharing options...
Uten Posted April 7, 2007 Share Posted April 7, 2007 Take a look at the arrays tutorial. If something is unclear or missing let me know.. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
petesa Posted April 11, 2007 Author Share Posted April 11, 2007 (edited) Thanks @Uten, your tutorial helped me with the array issue... Now I am working on some ObjGet Com issues, where not all registry values are returned.That is a very nice "Wiki Arrays Tutorial"; good basic introduction, great AutoIt code examples, gradually goes into more complex examples...even an array within an array section!FYI: The only thing that I noticed is a very minor grammar error: This makes sense in many situations as you now have a an array containing data with a an index starting at 1. Not really worth changing since this is a technical subject. :-) Edited April 11, 2007 by petesa Link to comment Share on other sites More sharing options...
dabus Posted April 11, 2007 Share Posted April 11, 2007 Simple question: If you got the uninstallstring, why don't you use it directly? Here is a sample I created some time ago to delete all java-stuff from a machine. At least it worked here. For $k = 1 To 1000 $Key = RegEnumKey("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $k) If @error <> 0 Then ExitLoop $DContact = RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $Key, 'Contact') If StringInStr($DContact, 'java') Then $MSI = RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $Key, 'UninstallString') $MSI = StringTrimLeft($MSI, 14) RunWait(@ComSpec & ' /c start /wait MsiExec.exe /X' & $MSI & ' /qn', 'C:', @SW_HIDE) EndIf Next The part I would like to point to is the runwait-line. Link to comment Share on other sites More sharing options...
petesa Posted April 12, 2007 Author Share Posted April 12, 2007 Thanks dabus, I was not aware of that there was a "built-in" RegEnumKey function! That is a great help. I tested a variation of your RegEnumKey function example and it works great! I had not considered running the "uninstallstring" directly (nested) because I thought that there may be more than one keyword match. The intention was to make a general use utility that accepts command line parameters. I will also need to detect different uninstallstring types (i.e. quiet, MSI, .exe, etc ), parse based on what is found, then do a RunWait to perform the uninstall. When I have it all working I will post the code here. Thank you again for responding. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now