none
vbscript check if registry key exists

    Question

  • Hi,

    what would be the code to find out of a registry key existed? for example i want to know if the following exists in the registry

    HKLM\Software\Microsoft\Windows\CurrentVersion\MyKey

    thanks

    Steve

    Wednesday, August 15, 2012 11:11 AM

Answers

  • OK, I tested with an empty string, not an unset (nul) string.  My bad.

    It would appear then to require the use of the EnumKeys method, followed by a FOR/Next loop to search for the key.

    If the test is to be done only on a local machine (strComputer always equal to dot), then this Wscript.Shell approach would work ...

    Dim sKey, bFound
    skey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Test\"
    '
    with CreateObject("WScript.Shell")
      on error resume next            ' turn off error trapping
        sValue = .regread(sKey)       ' read attempt
        bFound = (err.number = 0)     ' test for success
      on error goto 0                 ' restore error trapping
    end with
    '
    if bFound then
      wsh.echo "Found:", sValue
    else
      wsh.echo "Not found"
    end if

    Otherwise, try something like this ...

    Const HKEY_LOCAL_MACHINE = &H80000002
    '
    strComputer = "."
    '
    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
        strComputer & "\root\default:StdRegProv")
    '
    RegKey= "test"
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    '
    oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
    '
    For Each subkey In arrSubKeys
        bFound = (lcase(subkey) = lcase(regkey))
        if bFound then exit for
    Next
    '
    if bFound then
      wsh.echo "Found:", sValue
    else
      wsh.echo "Not found"
    end if


    Tom Lavedas

    • Marked as answer by Steve Mills Thursday, August 16, 2012 11:01 AM
    Wednesday, August 15, 2012 1:59 PM
    Moderator
  • The real issue is which registry do you want to create the key in. 

    If you just run that on a 32 bit system it will work the same as running it default on a 64 bit system except teh key will be created i the 64 bit 'view' of the registry.  A SysWoW64 does is give you a combined view of the registries by forcing all access to go through the SysWoW64 synthetic key maintained by the registry reflector which contains the 32 bit only registry keys.  This is only visible if you are running a script as a 64 bit process.

    The question you should answer is,  "do you want the value to be stored ONLY in the 32 bit registry or do you want it in both registry views?

    What process, 32 or 64 bit, does the key support?

    If you just write it to the registry on each system the key will be visible to all processes on either system.

    The best way to test this is to just run it on a 64 bit system and set the key then run the process that is going to read or alter the key.  I suspect that the process will see the key unless it is run in an isokated 32 bit process.

    See: http://support.microsoft.com/kb/305097

    The key for the installer should be visible to both subsystems.  YOu can use regedit to verify this.


    ¯\_(ツ)_/¯

    • Marked as answer by Steve Mills Thursday, August 16, 2012 11:02 AM
    Thursday, August 16, 2012 10:53 AM

All replies

  • Here is a article fro Hey Scripting Guy which does exactly that.

    Wednesday, August 15, 2012 11:27 AM
  • Have i missed something here, i have the code below but whether the key exists or not it always seems to return a null value

    Const HKEY_LOCAL_MACHINE = &H80000002
    Dim RegKey
    Dim objWshShell
    Set objWshShell = CreateObject("WScript.shell")

    strComputer = "."

    Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

    RegKey= "test"
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

    objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,RegKey,strValue

    'check if the value exists
    If IsNull(strValue) Then
    'the key doesnt exist

    End If

    Wednesday, August 15, 2012 12:14 PM
  • That is correct.  There is not such value at that location.

    Const HKEY_LOCAL_MACHINE = &H80000002
    Dim RegKey
    Dim objWshShell
    Set objWshShell = CreateObject("WScript.shell")
    strComputer = "."
    Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
    RegKey= "ProgramFilesPath"
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion"
    objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,RegKey,strValue
    'check if the value exists
    If Not IsNull(strValue) Then
    	MsgBox strValue
    End If


    ¯\_(ツ)_/¯

    Wednesday, August 15, 2012 12:52 PM
  • Are you sure it is a string value entry of the Uninstall key and not a key with that name?  If it is a string value your code works perfectly.  If it is a key named Test, it fails as you imply.

    To test for a key, you could try something like this ...

    Const HKEY_LOCAL_MACHINE = &H80000002
    Dim RegKey
    'Dim objWshShell
    'Set objWshShell = CreateObject("WScript.shell")
    '
    strComputer = "."
    '
    Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
    '
    RegKey= "test"
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    '
    objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath&"\"&RegKey, "",strValue
    '
    'check if the value exists
    If IsNull(strValue) Then
    'the key doesnt exist
      wsh.echo "Not found"
    else
      wsh.echo "Found:", strValue
    End If


    Tom Lavedas

    Wednesday, August 15, 2012 12:56 PM
    Moderator
  • Here is the beginner version.  It is much easier to use.

    Set WshShell = WScript.CreateObject("WScript.Shell")
    MsgBox WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesPath")


    ¯\_(ツ)_/¯

    Wednesday, August 15, 2012 12:57 PM
  • Yes i am trying to find out if a Key exists, not a value within the key. however, trying your code still seems to produce a null value, if i put the key there it will still think it doesnt exist and say "not found"
    Wednesday, August 15, 2012 1:29 PM
  • OK, I tested with an empty string, not an unset (nul) string.  My bad.

    It would appear then to require the use of the EnumKeys method, followed by a FOR/Next loop to search for the key.

    If the test is to be done only on a local machine (strComputer always equal to dot), then this Wscript.Shell approach would work ...

    Dim sKey, bFound
    skey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Test\"
    '
    with CreateObject("WScript.Shell")
      on error resume next            ' turn off error trapping
        sValue = .regread(sKey)       ' read attempt
        bFound = (err.number = 0)     ' test for success
      on error goto 0                 ' restore error trapping
    end with
    '
    if bFound then
      wsh.echo "Found:", sValue
    else
      wsh.echo "Not found"
    end if

    Otherwise, try something like this ...

    Const HKEY_LOCAL_MACHINE = &H80000002
    '
    strComputer = "."
    '
    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
        strComputer & "\root\default:StdRegProv")
    '
    RegKey= "test"
    strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    '
    oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
    '
    For Each subkey In arrSubKeys
        bFound = (lcase(subkey) = lcase(regkey))
        if bFound then exit for
    Next
    '
    if bFound then
      wsh.echo "Found:", sValue
    else
      wsh.echo "Not found"
    end if


    Tom Lavedas

    • Marked as answer by Steve Mills Thursday, August 16, 2012 11:01 AM
    Wednesday, August 15, 2012 1:59 PM
    Moderator
  • What i s perhaps most usefull is to check your rights on the key as a way of seeing if you can access it.

    const KEY_QUERY_VALUE = &H0001
    const HKEY_LOCAL_MACHINE = &H80000002
    Set objReg=GetObject("winmgmts:root\default:StdRegProv")
    strKeyPath = "SYSTEM\CurrentControlSet"
    '    right to query the SYSTEM\CurrentControlSet key
    objReg.CheckAccess HKEY_LOCAL_MACHINE, strKeyPath, KEY_QUERY_VALUE, bHasAccessRight
    If bHasAccessRight = True Then
        MsgBox "You have Query Value Access Rights"
    Else
        MsgBox "YOu have no access or key does not exixt."
    End If


    ¯\_(ツ)_/¯

    Wednesday, August 15, 2012 2:05 PM
  • It is much easier in PowerSHell

    $hklm=[Microsoft.Win32.REgistryKey]::OpenRemoteBaseKey('LocalMachine','.')
    if($hklm.OpenSubKey('SYSTEM\CurrentControlSet')){
         'key Exists'
    }else{
         'Key doesnt exist'


    ¯\_(ツ)_/¯

    Wednesday, August 15, 2012 2:17 PM
  • Haha, i think this might work, if it wasnt searching through the wow6432node of the registry. is there a way i can force it to search the normal path that i have put into that string, it seems to want to convert that to mean search under the wow6432node which is not what i want it to do.

    getting there :)

    Wednesday, August 15, 2012 3:13 PM
  • I'm guessing a little bit here because the script worked for me in Win7 Enterprise Edition.  My guess is that your environment is running the 64 bit version of the script engine - just a guess.   If I'm right, running this statement from the command prompt should include SYSWOW64 in the path reported ...

      C:\USER\yourid>ftype vbsfile
      vbsfile="%SystemRoot%\SYSWOW64\WScript.exe" "%1" %*

      C:\USER\yourid>

    If that's the case, you can try replacing the SYSWO64 location with System32 and see if that fixes the problem ...

      C:\USER\yourid>ftype vbsfile="%SystemRoot%\System32\WScript.exe" "%1" %*

    As I said, I'm guessing - in addition I can take no responsibility for any scripts that fail due to the change in the VBSfile FTYPE.


    Tom Lavedas


    Wednesday, August 15, 2012 4:13 PM
    Moderator
  • ahh, i really dont want to modify anything like you've suggested there and this also has to be run unattended on several machines so i cant really make alterations like that.

    i have the following code to write the registry key

    objRegistry.CreateKey HKEY_LOCAL_MACHINE, strKeyPath & RegKey

    if i write to the wow6432node and it doesnt exist because its a 32 bit system, will the script fail and bomb out on me? i am thinking of having two lines of code above, one for the normal 32 bit path and one for the 6432 path, but if its a 32 bit system that 6432node wont exist, would my script create it and "break" the registry by having it on a 32 bit system when it's not supposed to be there, or would it simply carry on with the script?

    Thursday, August 16, 2012 8:41 AM
  • The real issue is which registry do you want to create the key in. 

    If you just run that on a 32 bit system it will work the same as running it default on a 64 bit system except teh key will be created i the 64 bit 'view' of the registry.  A SysWoW64 does is give you a combined view of the registries by forcing all access to go through the SysWoW64 synthetic key maintained by the registry reflector which contains the 32 bit only registry keys.  This is only visible if you are running a script as a 64 bit process.

    The question you should answer is,  "do you want the value to be stored ONLY in the 32 bit registry or do you want it in both registry views?

    What process, 32 or 64 bit, does the key support?

    If you just write it to the registry on each system the key will be visible to all processes on either system.

    The best way to test this is to just run it on a 64 bit system and set the key then run the process that is going to read or alter the key.  I suspect that the process will see the key unless it is run in an isokated 32 bit process.

    See: http://support.microsoft.com/kb/305097

    The key for the installer should be visible to both subsystems.  YOu can use regedit to verify this.


    ¯\_(ツ)_/¯

    • Marked as answer by Steve Mills Thursday, August 16, 2012 11:02 AM
    Thursday, August 16, 2012 10:53 AM
  • What i have done to solve this is write to both registry locations, when the key is read it seems to detect it no problem as one of these locations will have the key. the key contains nothing under it and has no relevance to anything intricate to the system or specific to 32 or 64 bit systems, it is simply a marker to determine that a certain application has been installed once already.

    thanks guys for your explainations and sample code, much appreciated

    Thursday, August 16, 2012 11:04 AM
  • That will solve your issue too.

    You should NOT write to the installers key.  Only the installer (MSI) should write to that key.

    You cna build a quick installer package that will properly create a GUID and mark however you need uising the builtin IExpress Packager.  All you need to do is create asimple INI file in notepad and call iexpress.  It will create an EXE or MSI that can be used to update teh keys.  I am pretty sure it can take the 32/64 registry target also.


    ¯\_(ツ)_/¯

    Thursday, August 16, 2012 11:52 AM