petesa Posted April 7, 2007 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
Uten Posted April 7, 2007 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
petesa Posted April 11, 2007 Author 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
dabus Posted April 11, 2007 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.
petesa Posted April 12, 2007 Author 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.
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