Sign in to follow this  
Followers 0
BaldDragon

Registy Search/Delete Issue

11 posts in this topic

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?

$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

Share this post


Link to post
Share on other sites



Put a msg box that displays 2 pieces of information

1. What does "RegDelete($Results)" returns

2. What is the value of @error

Share this post


Link to post
Share on other sites

Put a msg box that displays 2 pieces of information

1. What does "RegDelete($Results)" returns

2. What is the value of @error

Thanks 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?

Share this post


Link to post
Share on other sites

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.

:P


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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

:P

Great! That was exactly what I needed. Thanks.

Share this post


Link to post
Share on other sites

#7 ·  Posted (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:

#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 by Lordofthestrings2

Share this post


Link to post
Share on other sites

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:

#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().

:D


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

Share this post


Link to post
Share on other sites

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


Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Thanks I got it working also :D

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 :D

#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 by Lordofthestrings2

Share this post


Link to post
Share on other sites

Thanks for this, it's helped me solve a problem in 20 minutes that would have taken > 1 day otherwise!!!

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