vb.net - 显示所有已安装的程序
问题描述
卡在一个错误上
System.NullReferenceException:“对象引用未设置为对象的实例。”
RSK 什么都不是。
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
我希望输出显示列表视图中所有已安装的程序,但实际输出是这个错误
System.NullReferenceException:“对象引用未设置为对象的实例。”
RSK 什么都不是。
解决方案
您的代码中的第一个问题是它作为 32 位应用程序运行。即使您设置了AnyCPU,最新版本的 Visual Studio 也会在您的项目属性中将 Prefer 32 位设置为 true。当作为 32 位应用程序运行时,Windows 会自动更改为打开密钥指定的路径,以指向Software子项中WOW6432Node中的相同路径。如果您遵循该路径但从WOW6432Node开始,您会注意到没有UserData子键,这将导致变量RSK为空
所以第一步是更改此属性,右键单击项目属性,然后查看构建页面。在这里,您应该看到标记了“首选 32 位”复选框。只需取消标记即可。
但是,即使在那之后,您也会发现您的代码再次因NullReferenceException而失败。这次问题是由于您盲目地假设列出的每个程序都存在子项“InstallProperties”而引起的。
您可以将代码更改为更安全的方法
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
推荐阅读
- angular - 如何在 ngFor 中动态生成 mat-select
- raspberry-pi3 - 从 Voice Bonnet 访问 GPIO
- git - git log 文件名错误:不明确的参数文件名未知修订
- django - Docker Django uWSGI 奇怪的连接错误
- python - 它是如何在 Python 中的下一行代码的底层工作的?
- javascript - javascript点击事件的问题
- swift - 在 Swift Foundation Measurements 框架中使用年单位间隔
- android - 是否可以从 FileProvider 生成的 URI 获取文件路径?
- pyomo - 通过 DataPortal 将 JSON 数据加载到参数中
- java - 我可以使用通用方法来访问休眠中不同实体的数据吗