0
votes

I am using the following code, however it doesn't seem to matter how I call the registry, I always get a fail or fail to default value on protected registry keys.

The interesting part, is that when running a VBScript, I have no issues accessing these keys.

Const Key As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\"

Public Overloads ReadOnly Property ProductName As String
    Get
        Return DirectCast(My.Computer.Registry.LocalMachine.GetValue(Key & "ProductName"), String)
        '            Dim WshShell As Object = CreateObject("WScript.Shell")
        '            Return WshShell.RegRead(Key & "ProductName")
    End Get
End Property

Public ReadOnly Property DigitalID As String
    Get
        Return DirectCast(My.Computer.Registry.LocalMachine.GetValue(Key & "DigitalProductId"), String)
        '            Dim WshShell As Object = CreateObject("WScript.Shell")
        '            Return WshShell.RegRead(Key & "DigitalProductId")
    End Get
End Property

Public ReadOnly Property PID As String
    Get
        Return DirectCast(My.Computer.Registry.LocalMachine.GetValue(Key & "ProductID"), String)
        '            Dim WshShell As Object = CreateObject("WScript.Shell")
        '            Return WshShell.RegRead(Key & "ProductID")
    End Get
End Property

Public ReadOnly Property ProductKey As String
    Get
        Try
            Dim pKey As Byte() = System.Text.Encoding.Default.GetBytes(DigitalID)
            Dim Chars As String = "BCDFGHJKMPQRTVWXY2346789"
            Dim i As Integer = 24
            Dim isWin8 As Integer = (pKey(66) \ 6) And 1
            Dim Cur As Integer = 0
            Dim x As Integer = 14
            Dim Last As Integer = 0
            Dim keypart1 As String = ""

            Dim insert As String = ""
            Dim a As String = ""
            Dim b As String = ""
            Dim c As String = ""
            Dim d As String = ""
            Dim e As String = ""
            Dim KeyOutput As String = ""

            Const KeyOffset = 52
            pKey(66) = (pKey(66) And &HF7) Or ((isWin8 And 2) * 4)
            i = 24
            Chars = "BCDFGHJKMPQRTVWXY2346789"
            Do
                Cur = 0
                x = 14
                Do
                    Cur = Cur * 256
                    Cur = pKey(x + KeyOffset) + Cur
                    pKey(x + KeyOffset) = (Cur \ 24)
                    Cur = Cur Mod 24
                    x = x - 1
                Loop While x >= 0
                i = i - 1
                KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput
                Last = Cur
            Loop While i >= 0
            If (isWin8 = 1) Then
                keypart1 = Mid(KeyOutput, 2, Last)
                insert = "N"
                KeyOutput = Replace(KeyOutput, keypart1, keypart1 & insert, 2, 1, 0)
                If Last = 0 Then KeyOutput = insert & KeyOutput
            End If
            a = Mid(KeyOutput, 1, 5)
            b = Mid(KeyOutput, 6, 5)
            c = Mid(KeyOutput, 11, 5)
            d = Mid(KeyOutput, 16, 5)
            e = Mid(KeyOutput, 21, 5)
            Return a & "-" & b & "-" & c & "-" & d & "-" & e
        Catch er As Exception
            Return er.Message
        End Try
    End Get
End Property

When testing with WshShell, I had 'Key' set to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ and also tried HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ . I also tried with or without a slash at the beginning, and end, and even hardcoding the entire key.

The problem I am getting is that all of these registry keys are returning nothing, and I can not find how to set the permission necessary to be able to open them, as I can see them using RegEdit, and I can also access them using VBScript.

Thanks in advance.

1
You'll need to do the same thing that VBScript does, allow your program to run in 64-bit mode so you can read these 64-bit registry keys. Project + Properties, Compile tab, set the Target CPU to "AnyCPU", untick the Prefer 32-bit checkbox if you see it. - Hans Passant
Thank you. Between your command and Drunken Code Monkeys answer, was the entire solution. Neither solved the issue by themselves. - Kraang Prime

1 Answers

1
votes

You need to open the subkey before you can read the value:

Const Key As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\"

Public Overloads ReadOnly Property ProductName As String
    Get
        Return My.Computer.Registry.LocalMachine.OpenSubKey(Key).GetValue("ProductName").ToString
    End Get
End Property

EDIT: As noted above by Hans Passant, the build platform needs to be set to the "native" platform for the Windows installation (x64 or Any CPU for a 64-bits Windows), as the DigitalProductId (amongst others) value only exists in the "native" branch of the registry. The best bet is to leave it to AnyCPU to be sure to be able to read the value on any client PC.