Search code examples
vb.netregistry

Check Registry if Hive or Key Exists?


I am just trying to do a simple check if a registry location exists and the answers from other questions here are not working. Here is my code. I have a label for ON and a label for OFF that are just the entry is found or not. I have the registry entry in but not getting the labels to flip. FriendlyName is a key in 7&639dc5f&0&0000.

Private Sub CheckUSB_Serial()
If My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04E2&PID_1422&MI_00\7&639dc5f&0&0000", _
                                     "FriendlyName", Nothing) Is Nothing Then
        USB_SERIAL_ON.Visible = False
        USB_SERIAL_OFF.Visible = True
    Else
        USB_SERIAL_ON.Visible = True
        USB_SERIAL_OFF.Visible = False
    End If
End Sub

Solution

  • Starting with .NET Framework 4 (I believe), RegistryKey.OpenBaseKey is available which allows one to specify a Registry View. This is particularly useful when attempting to read the 64-bit registry on a 64-bit OS when one's application is running as 32-bit. It works for both 32-bit and 64-bit operating systems. RegistryKey.OpenSubKey is used in conjunction with RegistryKey.OpenBaseKey.

    According to the documentation, OpenSubKey returns null (Nothing) if the operation failed. It also raises the following exceptions:

    • ArgumentNullException
    • ObjectDisposedException
    • Security Exception

    Therefore if one attempts to open a registry subkey and the value is null (Nothing), the key doesn't exist.

    Try the following:

    Add the following imports statement

    • Imports Microsoft.Win32

    SubkeyExists:

    Public Function SubkeyExists(hive As RegistryHive, subkey As String, Optional regView As RegistryView = RegistryView.Registry64) As Boolean
        'open specified registry hive with specified RegistryView
        Using rKey As RegistryKey = RegistryKey.OpenBaseKey(hive, regView)
            If rKey IsNot Nothing Then
                Using sKey As RegistryKey = rKey.OpenSubKey(subkey, False)
                    If sKey IsNot Nothing Then
                        Return True
                    Else
                        Return False
                    End If
                End Using
            Else
                Throw New Exception($"Error (SubkeyExists) - Could Not open '{hive.ToString()}' ")
            End If
        End Using
    End Function
    

    Usage:

    Dim result As Boolean = SubkeyExists(RegistryHive.LocalMachine, "SYSTEM\CurrentControlSet\Enum\USB\VID_04E2&PID_1422&MI_00\7&639dc5f&0&0000")
    'Dim result As Boolean = SubkeyExists(RegistryHive.LocalMachine, "SYSTEM\CurrentControlSet\Enum\USB\VID_04E2&PID_1422&MI_00\7&639dc5f&0&0000", RegistryView.Default)
    

    Alternatively, one could use recursion to check if each portion of the registry subkey exists (left-to-right).


    To get a value from a ValueName within a specified subkey, one can use the following:

    GetRegistryValue:

    Public Function GetRegistryValue(hive As RegistryHive, subkey As String, valueName As String, Optional regView As RegistryView = RegistryView.Registry64) As Object
        Using rKey As RegistryKey = RegistryKey.OpenBaseKey(hive, regView)
            If rKey IsNot Nothing Then
    
                'open subkey
                Using sKey As RegistryKey = rKey.OpenSubKey(subkey, False)
                    If sKey IsNot Nothing Then
                        'read from registry
                        'Debug.WriteLine($"'{valueName}' Data Type: {sKey.GetValueKind(valueName)}")
                        Return sKey.GetValue(valueName)
                    Else
                        Throw New Exception($"Error (GetRegistryValue) - Could not open '{subkey}'")
                    End If
                End Using
            Else
                Throw New Exception($"Error (GetRegistryValue) - Could Not open '{hive.ToString()}' ")
            End If
        End Using
    End Function
    

    Usage

    Dim result As String = CType(GetRegistryValue(RegistryHive.LocalMachine, "SYSTEM\CurrentControlSet\Enum\USB\VID_04E2&PID_1422&MI_00\7&639dc5f&0&0000", "FriendlyName"), String)