Jump to content

Searching registry with RegEnumVal and Key


Recommended Posts

Hello, first and foremost this is a great program and the forums have been a great help to me so far. I barely know anything about programming or scripting and after only two weeks I feel like I've learned a great deal. However, my brain is still not conditioned for this 100%, so I need some help. (I'm also longwinded, for that I apologize.)

I'm trying to write a script that will uninstall adobe AIR and Acrobat.com for use on a few hundred computers I support at work. Adobe AIR has an installer that, if run by CMD prompt with a -uninstall flag will uninstall all versions (supposedly). Acrobat.com doesn't even give us that grace, it just has an entry in Add/Remove programs (so does AIR). I'd go to the registry and just pull the Uninstall string, but their uninstallation subkeys move around in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ key depending on what version it is.

So here's the plan: I plan to use RegEnumKey and RegEnumVal (if possible) to search all subkeys that start with a curly bracket (or eventually all subkeys, some aren't in {}s), search them for any entries that have a value of Adobe AIR or Acrobat.com (Usually in the Display Name entry), and if it matches that pull out the uninstall string entry's value. Then take that value, toss it into a cmd prompt, uninstall, and wipe my hands clean.

a) is my logic sound? or would this not work due to an obvious flaw?

b ) my first stumbling block is trying to use the 'for' loop like in the example, since I don't know any upper bound, and I don't think I can use Ubound in this case, unless I first have it throw all the subkeys into an array, count them and get an upper bound that way. Should I be using a while?

c) how do I nest regenumval into Regenumkey so that for each subkey it'll check the values for the one I want? i'm not even sure how to have it search the entries for the specific values, for that matter.

Any direction would be greatly appreciated!

Link to comment
Share on other sites

Edit: Okay, I lied. Question - why does the output change depending on whether or not I use a string or an Array? Neither of them seem to parse the results properly. This is my code I'm using

#include <array.au3>

$hkeyloc="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$AIR="Adobe Air"

$results=_regsearch($hkeyloc, $AIR, 7, true)

fileopen("C:Documents and settings\administrator\desktop\results.txt",10)

;~$i=0 ;write results to txt file
;~while $i < 4
;~filewrite("C:Documents and settings\administrator\desktop\results.txt",$results[$i])
;~filewrite("C:Documents and settings\administrator\desktop\results.txt",@CR)
;~$i=$i+1
;~wend

_arrayDisplay($results)

Func RegSearch(...

The array window that comes up has the last two entries joined, so instead of looking like...

4
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\DisplayName = Adobe AIR
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\UninstallString = c:\Program Files\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\{A2BCA9F1-566C-4805-97D1-7FDC93386723}\DisplayName = Adobe AIR

it looks like...

3
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\DisplayName = Adobe AIR
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\Adobe AIR\UninstallString = c:\Program Files\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe -arp:uninstallHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\\{A2BCA9F1-566C-4805-97D1-7FDC93386723}\DisplayName = Adobe AIR

which makes it pretty difficult to see what I'm working with. Both the message box and the array aren't displaying this properly. What am I doing wrong?

Edited by squid808
Link to comment
Share on other sites

Looks like a bug to me. I get the same thing. Strange it hasn't been reported before. I'm debugging now and will post the fix. The double backslash before the last path element shouldn't be there either.

:mellow:

Edit: Just add this to the top of the function to remove the stray double backslash:

; Trim trailing backslash, if present
    If StringRight($sStartKey, 1) = "\" Then $sStartKey = StringTrimRight($sStartKey, 1)

Still looking at the joined strings.

:P

Edited by PsaltyDS
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

Tweaked version 2.0.3.0, fixing bug reported by squid808:

;*****************************************************
; 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 (defualt = 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
;  v2.0.2.0  |  11/12/08  |  Fixed bug returning array [0] = 1 vice 0 for none found
;  v2.0.3.0  |  06/22/10  |  Fixed bug appending some result strings together reported by squid808
;*****************************************************
Func _RegSearch($sStartKey, $sSearchVal, $iType = 0x07, $fArray = False)
    Local $v, $sVal, $k, $sKey, $sFound = "", $sFoundSub = "", $avFound[1] = [0]

    ; Trim trailing backslash, if present
    If StringRight($sStartKey, 1) = "\" Then $sStartKey = StringTrimRight($sStartKey, 1)

    ; 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
            $sFoundSub = _RegSearch($sStartKey & "\" & $sKey, $sSearchVal, $iType, False) ; use string mode to test sub keys
            If $sFoundSub <> "" Then $sFound &= $sFoundSub & @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
        If StringStripWS($sFound, 8) <> "" Then $avFound = StringSplit($sFound, @LF)
        Return $avFound
    Else
        Return $sFound
    EndIf
EndFunc   ;==>_RegSearch

:mellow:

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

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...