BaldDragon Posted July 30, 2008 Share Posted July 30, 2008 I need to search the registry for all keys and delete them. I've used the RegSearch func and it's working great, but I can't seem to get it to delete the results. I commented out the the loop that checks for values to speed it up. I also had it push out to a message box to make sure I'm getting the correct results. Can anyone help me see what I'm missing? expandcollapse popup$SearchKey = "HKLM\SOFTWARE\Classes" $SearchString = "Test.Key" $Results = _RegSearch($SearchKey, $SearchString) ;MsgBox(64, "_RegSearch() Test", $Results) RegDelete($Results) ;~RegSearch Func _RegSearch($startkey, $searchval) Local $v, $val, $k, $key, $found = "" ; This loop checks values ;~ $v = 1 ;~ While 1 ;~ $val = RegEnumVal($startkey, $v) ;~ If @error = 0 Then ;~ ; Valid value - test it's name ;~ If StringInStr($val, $searchval) Then ;~ $found = $found & $startkey & "\" & $val & @LF ;~ EndIf ;~ ; test it's data ;~ $readval = RegRead($startkey, $val) ;~ If StringInStr($readval, $searchval) Then ;~ $found = $found & $startkey & "\" & $val & " = " & $readval & @LF ;~ EndIf ;~ $v += 1 ;~ Else ;~ ; No more values here ;~ ExitLoop ;~ EndIf ;~ WEnd ; This loop checks subkeys $k = 1 While 1 $key = RegEnumKey($startkey, $k) If @error = 0 Then ; Valid key - test it's name If StringInStr($key, $searchval) Then $found = $found & $startkey & "\" & $key & "\" & @LF EndIf ; Now search it $found = $found & _RegSearch($startkey & "\" & $key, $searchval) Else ; No more keys here ExitLoop EndIf $k += 1 WEnd ; Return results Return $found EndFunc ;==>_RegSearch Link to comment Share on other sites More sharing options...
Juvigy Posted July 30, 2008 Share Posted July 30, 2008 Put a msg box that displays 2 pieces of information 1. What does "RegDelete($Results)" returns 2. What is the value of @error Link to comment Share on other sites More sharing options...
BaldDragon Posted July 30, 2008 Author Share Posted July 30, 2008 Put a msg box that displays 2 pieces of information 1. What does "RegDelete($Results)" returns2. What is the value of @errorThanks for the quick response Juvigy. Ok, Regdelete returns a 0 which is key/value does not exist and @error returns 1 which is unable to open requested key. If there is only 1 result returned, Regdelete($results) works fine, but more than one gives these errors. Should I pipe $results out to an array and then read each line individually?Anyone know a better way to do it? Link to comment Share on other sites More sharing options...
PsaltyDS Posted July 30, 2008 Share Posted July 30, 2008 I need to search the registry for all keys and delete them. I've used the RegSearch func and it's working great, but I can't seem to get it to delete the results. I commented out the the loop that checks for values to speed it up. I also had it push out to a message box to make sure I'm getting the correct results. Can anyone help me see what I'm missing? I have updated the _RegSearch() function to include flags for return types. Try your search with the new version as: $avResults = _RegSearch($SearchKey, $SearchString, 1, 1) This will return only matching key names (not value names or data matches) and will return $avResults as an array. Then you can loop through the array to do your deletes. 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 Link to comment Share on other sites More sharing options...
Juvigy Posted July 31, 2008 Share Posted July 31, 2008 Make the _regsearch to return either 0 if it doesnt find enything or to return only the first found key. After that it is easy - make a loop that runs the find and then delete functions until your regserach function return 0. Link to comment Share on other sites More sharing options...
BaldDragon Posted July 31, 2008 Author Share Posted July 31, 2008 I have updated the _RegSearch() function to include flags for return types. Try your search with the new version as: $avResults = _RegSearch($SearchKey, $SearchString, 1, 1) This will return only matching key names (not value names or data matches) and will return $avResults as an array. Then you can loop through the array to do your deletes. Great! That was exactly what I needed. Thanks. Link to comment Share on other sites More sharing options...
lordofthestrings Posted September 28, 2009 Share Posted September 28, 2009 (edited) I have a question about this: I 'm now using your function to "seek and destroy" a string in the registry. I added a few bogus strings and look for them. then I want to autodelete them.. not that easy: as you can see I have a key, a value, and data with the searchstring. HKLM\SOFTWARE\AXA\SEEQL HKLM\SOFTWARE\AXA\MyJunk = SEEQL HKLM\SOFTWARE\AXA\SEEQL\ How would I delete these? first one works without a problem. here's my code: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_outfile=RegDestroy.exe #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** If $cmdline[0] = 0 Then ConsoleWrite("please enter 2 command line arguments: 1) Key_2_Search and 2) Reghive" & @CRLF & _ "example: regdestroy SQL HKLM " & @CRLF & _ "will kill all regkeys containing SQL (only use when certain)" & @CRLF) Exit EndIf $SearchString = $cmdline[1] $SearchKey = $cmdline[2] ; Find only data, return as an array $Results = _RegSearch($SearchKey, $SearchString, 1, 1) ; ConsoleWrite("results is an array of: " & $results[0] & @CRLF) For $i = 1 to $Results[0] ConsoleWrite("Removing: " & $Results[$i] & @LF) RegDelete($Results[$i]) Next ;***************************************************** ; Function _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) ; Where: $sStartKey = Reg path at which to begin search ; $sSearchVal = The string to search for ; $iType = Matching types to return: ; 1 = Key names ; 2 = Value names ; 4 = Value data ; Add bits together for multiple match types, default is 7 (all) ; $fArray = Return an array of results vice the string (default = False) ; Performs a recursive search of the registry starting at $sStartKey, looking for $sSearchVal ; Returns a string containing a list of key names and values. ; If a key name matches, it is listed as a reg path with trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ ; If a value name matches, it is listed as a reg path without trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir ; If the data matches, the format is path = data: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir = %SystemRoot%\Web\Wallpaper ; If $fArray is True, then return data is an array with [0] = count. ;***************************************************** ; Change Log: ; v1.0.0.0 | 03/17/05 | Original SearchReg() by Holger ; v2.0.0.0 | 08/10/06 | Native AutoIt version by PsaltyDS ; v2.0.0.1 | 08/16/06 | Fixed bug reported by markloman ; v2.0.1.0 | 07/30/08 | Added $iType and $fArray parameters ;***************************************************** Func _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) Local $v, $sVal, $k, $sKey, $sFound = "" ; Generate type flags If Not BitAND($iType, 0x07) Then Return SetError(1, 0, 0); No returns selected Local $fKeys = BitAND($iType, 0x1), $fValue = BitAND($iType, 0x2), $fData = BitAND($iType, 0x4) ; This checks values and data in the current key If ($fValue Or $fData) Then $v = 1 While 1 $sVal = RegEnumVal($sStartKey, $v) If @error = 0 Then ; Valid value - test its name If $fValue And StringInStr($sVal, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & @LF ; test its data If $fData Then $readval = RegRead($sStartKey, $sVal) If StringInStr($readval, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & " = " & $readval & @LF EndIf EndIf $v += 1 Else ; No more values here ExitLoop EndIf WEnd EndIf ; This loop checks subkeys $k = 1 While 1 $sKey = RegEnumKey($sStartKey, $k) If @error = 0 Then ; Valid key - test it's name If $fKeys And StringInStr($sKey, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sKey & "\" & @LF ; Now search it $sFound &= _RegSearch($sStartKey & "\" & $sKey, $sSearchVal, $iType) Else ; No more keys here ExitLoop EndIf $k += 1 WEnd ; Return results If StringRight($sFound, 1) = @LF Then $sFound = StringTrimRight($sFound, 1) If $fArray Then Return StringSplit($sFound, @LF) Else Return $sFound EndIf EndFunc ;==>_RegSearch Edited September 28, 2009 by Lordofthestrings2 Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 28, 2009 Share Posted September 28, 2009 I have a question about this: I 'm now using your function to "seek and destroy" a string in the registry. I added a few bogus strings and look for them. then I want to autodelete them.. not that easy: as you can see I have a key, a value, and data with the searchstring. HKLM\SOFTWARE\AXA\SEEQL HKLM\SOFTWARE\AXA\MyJunk = SEEQL HKLM\SOFTWARE\AXA\SEEQL\ How would I delete these? first one works without a problem. here's my code: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_outfile=RegDestroy.exe #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** If $cmdline[0] = 0 Then ConsoleWrite("please enter 2 command line arguments: 1) Key_2_Search and 2) Reghive" & @CRLF & _ "example: regdestroy SQL HKLM " & @CRLF & _ "will kill all regkeys containing SQL (only use when certain)" & @CRLF) Exit EndIf $SearchString = $cmdline[1] $SearchKey = $cmdline[2] ; Find only data, return as an array $Results = _RegSearch($SearchKey, $SearchString, 1, 1) ; ConsoleWrite("results is an array of: " & $results[0] & @CRLF) For $i = 1 to $Results[0] ConsoleWrite("Removing: " & $Results[$i] & @LF) RegDelete($Results[$i]) Next ;***************************************************** ; Function _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) ; Where: $sStartKey = Reg path at which to begin search ; $sSearchVal = The string to search for ; $iType = Matching types to return: ; 1 = Key names ; 2 = Value names ; 4 = Value data ; Add bits together for multiple match types, default is 7 (all) ; $fArray = Return an array of results vice the string (default = False) ; Performs a recursive search of the registry starting at $sStartKey, looking for $sSearchVal ; Returns a string containing a list of key names and values. ; If a key name matches, it is listed as a reg path with trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ ; If a value name matches, it is listed as a reg path without trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir ; If the data matches, the format is path = data: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir = %SystemRoot%\Web\Wallpaper ; If $fArray is True, then return data is an array with [0] = count. ;***************************************************** ; Change Log: ; v1.0.0.0 | 03/17/05 | Original SearchReg() by Holger ; v2.0.0.0 | 08/10/06 | Native AutoIt version by PsaltyDS ; v2.0.0.1 | 08/16/06 | Fixed bug reported by markloman ; v2.0.1.0 | 07/30/08 | Added $iType and $fArray parameters ;***************************************************** Func _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) Local $v, $sVal, $k, $sKey, $sFound = "" ; Generate type flags If Not BitAND($iType, 0x07) Then Return SetError(1, 0, 0); No returns selected Local $fKeys = BitAND($iType, 0x1), $fValue = BitAND($iType, 0x2), $fData = BitAND($iType, 0x4) ; This checks values and data in the current key If ($fValue Or $fData) Then $v = 1 While 1 $sVal = RegEnumVal($sStartKey, $v) If @error = 0 Then ; Valid value - test its name If $fValue And StringInStr($sVal, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & @LF ; test its data If $fData Then $readval = RegRead($sStartKey, $sVal) If StringInStr($readval, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & " = " & $readval & @LF EndIf EndIf $v += 1 Else ; No more values here ExitLoop EndIf WEnd EndIf ; This loop checks subkeys $k = 1 While 1 $sKey = RegEnumKey($sStartKey, $k) If @error = 0 Then ; Valid key - test it's name If $fKeys And StringInStr($sKey, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sKey & "\" & @LF ; Now search it $sFound &= _RegSearch($sStartKey & "\" & $sKey, $sSearchVal, $iType) Else ; No more keys here ExitLoop EndIf $k += 1 WEnd ; Return results If StringRight($sFound, 1) = @LF Then $sFound = StringTrimRight($sFound, 1) If $fArray Then Return StringSplit($sFound, @LF) Else Return $sFound EndIf EndFunc ;==>_RegSearch Look at the $iType parameter explanation more closely in the function's header. Use 7 (1+2+4) vice 1 to get all types: $Results = _RegSearch($SearchKey, $SearchString, 7, 1) Your loop would also have to evaluate each entry in the returned array to delete either the key or the value as appropriate with RegDelete(). 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 Link to comment Share on other sites More sharing options...
lordofthestrings Posted September 29, 2009 Share Posted September 29, 2009 I'll give it a go today, I thought regdelete was not going to be able to handle the different types. thanks for looking into it! kind regards, Dimitri Link to comment Share on other sites More sharing options...
lordofthestrings Posted September 29, 2009 Share Posted September 29, 2009 (edited) Thanks I got it working also I Did have to make one or 2 small adjustments to the regsearch function though.. it didn't place a @LF at the end of the array of the "key", this just appended, and resulted in a failure to remove the key. Here's the code, in case anyone finds it usefull expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_outfile=RegDestroy.exe #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Run_Obfuscator=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <array.au3> If $cmdline[0] = 0 Then ConsoleWrite("please enter 2 command line arguments: 1) Key_2_Search and 2) Reghive" & @CRLF & _ "examples: regdestroy SQL HKLM " & @CRLF & _ "regdestroy MSCRM HKCU" & @CRLF & _ "will kill all regkeys containing SQL or MSCRM from HKLM or HKCU" & @CRLF) Exit EndIf $SearchString = $cmdline[1] $SearchKey = $cmdline[2] Kill_Reg($SearchKey, $SearchString) Func Kill_Reg($SearchKey, $SearchString) $Results = _RegSearch($SearchKey, $SearchString, 7, 1) ; _ArrayDisplay($Results) For $i = 1 to $Results[0] $key = "" if stringright($Results[$i], 1) = "\" Then $sType = "Key" RegDelete($Results[$i]) ConsoleWrite($Results[$i] & "(" & $sType & ")" & @CRLF) Else if StringInStr($Results[$i], "=") <> 0 Then $sType = "Data" $splitted_string = StringSplit($Results[$i],"=") $Value = StringTrimLeft($splitted_string[1], StringInStr($splitted_string[1],"\",0, -1)) $key = stringtrimright($splitted_string[1], stringlen(StringTrimLeft($splitted_string[1], StringInStr($splitted_string[1],"\",0, -1)))) $stripped_String = StringStripWS($Value, 3) RegDelete($key, $stripped_String) ConsoleWrite($key & ", " & $stripped_String & " (" & $sType & ")" & @CRLF) Else if not $Results[$i] = "" Then $sType = "Value" $position_of_slash = StringInStr($Results[$i],"\",0, -1) $lenght_result = StringLen($Results[$i]) $2remove = $lenght_result - $position_of_slash $key = StringTrimRight($Results[$i], $2remove) $Value = StringTrimLeft($Results[$i], $position_of_slash) RegDelete($key, $Value) ConsoleWrite($key & ", " & $Value & " (" & $sType & ")" & @CRLF) ; Else ; ContinueLoop EndIf EndIf EndIf Next ConsoleWrite("all done!" & @CRLF) EndFunc ;***************************************************** ; Function _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) ; Where: $sStartKey = Reg path at which to begin search ; $sSearchVal = The string to search for ; $iType = Matching types to return: ; 1 = Key names ; 2 = Value names ; 4 = Value data ; Add bits together for multiple match types, default is 7 (all) ; $fArray = Return an array of results vice the string (default = False) ; Performs a recursive search of the registry starting at $sStartKey, looking for $sSearchVal ; Returns a string containing a list of key names and values. ; If a key name matches, it is listed as a reg path with trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ ; If a value name matches, it is listed as a reg path without trailing backslash: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir ; If the data matches, the format is path = data: ; i.e. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WallPaperDir = %SystemRoot%\Web\Wallpaper ; If $fArray is True, then return data is an array with [0] = count. ;***************************************************** ; Change Log: ; v1.0.0.0 | 03/17/05 | Original SearchReg() by Holger ; v2.0.0.0 | 08/10/06 | Native AutoIt version by PsaltyDS ; v2.0.0.1 | 08/16/06 | Fixed bug reported by markloman ; v2.0.1.0 | 07/30/08 | Added $iType and $fArray parameters ;***************************************************** Func _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False) Local $v, $sVal, $k, $sKey, $sFound = "" ; Generate type flags If Not BitAND($iType, 0x07) Then Return SetError(1, 0, 0); No returns selected Local $fKeys = BitAND($iType, 0x1), $fValue = BitAND($iType, 0x2), $fData = BitAND($iType, 0x4) ; This checks values and data in the current key If ($fValue Or $fData) Then $v = 1 While 1 $sVal = RegEnumVal($sStartKey, $v) If @error = 0 Then ; Valid value - test its name If $fValue And StringInStr($sVal, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & @LF ; test its data If $fData Then $readval = RegRead($sStartKey, $sVal) If StringInStr($readval, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sVal & " = " & $readval & @LF EndIf EndIf $v += 1 Else ; No more values here ExitLoop EndIf WEnd EndIf ; This loop checks subkeys $k = 1 While 1 $sKey = RegEnumKey($sStartKey, $k) If @error = 0 Then ; Valid key - test it's name If $fKeys And StringInStr($sKey, $sSearchVal) Then $sFound &= $sStartKey & "\" & $sKey & "\" & @LF ; Now search it $sFound &= _RegSearch($sStartKey & "\" & $sKey, $sSearchVal, $iType) & @LF Else ; No more keys here ExitLoop EndIf $k += 1 WEnd ; Return results If StringRight($sFound, 1) = @LF Then $sFound = StringTrimRight($sFound, 1) If $fArray Then Return StringSplit($sFound, @LF) Else Return $sFound EndIf EndFunc ;==>_RegSearch Edited September 30, 2009 by Lordofthestrings2 Link to comment Share on other sites More sharing options...
ModemJunki Posted January 29, 2010 Share Posted January 29, 2010 Thanks for this, it's helped me solve a problem in 20 minutes that would have taken > 1 day otherwise!!! Always carry a towel. 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