-2

Stuck on a single error

System.NullReferenceException: 'Object reference not set to an instance of an object.'

RSK was Nothing.

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Listname()
    End Sub
    Private Sub Listname()
        Dim soft As String() = Nothing
        Dim softkey As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products"
        Using RSK As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey)
            For Each RSKName As String In RSK.GetSubKeyNames
                'get sub key


                Dim name = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey).OpenSubKey(RSKName).OpenSubKey("InstallProperties").GetValue("DisplayName")
                Dim installlocal = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey).OpenSubKey(RSKName).OpenSubKey("InstallProperties").GetValue("InstallLocation")
                Dim pub = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey).OpenSubKey(RSKName).OpenSubKey("InstallProperties").GetValue("Publisher")
                Dim Uninstall = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey).OpenSubKey(RSKName).OpenSubKey("InstallProperties").GetValue("UninstallString")

                If name.ToString <> "" Then
                    Dim lst As New ListViewItem
                    lst.Text = name.ToString
                    lst.SubItems.Add(installlocal.ToString)
                    lst.SubItems.Add(pub.ToString)
                    ListView1.Items.Add(lst)

                End If

            Next
        End Using
    End Sub
End Class

I expect the output to show all the installed programs in listview but the actual output is this error

System.NullReferenceException: 'Object reference not set to an instance of an object.'

RSK was Nothing.

Trevor
  • 7,777
  • 6
  • 31
  • 50
gtXs
  • 3
  • 1
  • 3
  • According to the documentation [OpenSubKey](https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registrykey.opensubkey?view=netframework-4.8#Microsoft_Win32_RegistryKey_OpenSubKey_System_String_) returns `Nothing` if the operation failed. The key might be missing in the registry. You might have to call CreateSubKey or use a default value if it is missing. – Olivier Jacot-Descombes Sep 03 '19 at 14:49
  • 1
    See [OpenSubKey() returns null for a registry key that I can see in regedit.exe](https://stackoverflow.com/q/13728491/719186) – LarsTech Sep 03 '19 at 14:52
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Trevor Sep 03 '19 at 17:41

1 Answers1

0

The first problem in your code is that it is running as a 32 bit application. Even if you have the AnyCPU set, the latest versions of Visual Studio set the Prefer 32 bit to true in your project properties. When runnig as a 32bit application, the path specified to open the key is automatically changed by Windows to point to the same path in the WOW6432Node in the Software subkey. If you follow that path but starting from the WOW6432Node you will notice that there isn't a UserData subkey, and this will lead to the variable RSK to be nothing

So the first step is to change this property right clicking on the project properties and then looking at the Build page. Here you should see the "Prefer 32 bit" checkbox marked. Just unmark it.

But, even after that, you will find your code fail again for a NullReferenceException. This time the problem is caused by you blindly assuming that the subkey "InstallProperties" exists for every program listed.

You could change your code to a more safe approach

Private Sub Listname()
    Dim soft As String() = Nothing
    Dim softkey As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products"
    Using RSK As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey, RegistryKeyPermissionCheck.ReadSubTree)
        For Each RSKName As String In RSK.GetSubKeyNames
            Dim name As String = ""
            Dim installlocal As String = ""
            Dim pub As String = ""
            Dim Uninstall As String = ""

            Dim kname = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(softkey).OpenSubKey(RSKName).OpenSubKey("InstallProperties")
            If kname IsNot Nothing Then
                name = kname.GetValue("DisplayName", "").ToString()
                installlocal = kname.GetValue("InstallLocation", "").ToString()
                pub = kname.GetValue("Publisher", "").ToString()
                Uninstall = kname.GetValue("UninstallString", "").ToString()
            End If

            If Not String.IsNullOrEmpty(name) Then
                Dim lst As New ListViewItem
                lst.Text = name
                lst.SubItems.Add(installlocal)
                lst.SubItems.Add(pub)
                ListView1.Items.Add(lst)

            End If


        Next
    End Using
End Sub
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Good answer, although I would either turn `Option Strict On` and or use the overload to specify the default return value if key isn't found using `.GetValue` as it returns `Object`. – Trevor Sep 03 '19 at 17:45
  • Yes, agree. Always _Option Strict On_ – Steve Sep 03 '19 at 18:08