打开我知道存在的子项时出现NullReferenceException

时间:2018-01-28 22:40:46

标签: vb.net visual-studio-2013 registry nullreferenceexception

我尝试打开注册表项,以便删除其子项:

Dim asu As New System.Security.Principal.NTAccount(username.Text)
Dim si As System.Security.Principal.SecurityIdentifier = asu.Translate(GetType(System.Security.Principal.SecurityIdentifier))

Dim MyReg As Microsoft.Win32.RegistryKey
MyReg = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, host.Text) _
    .OpenSubKey("Software\Microsoft\Windows NT\currentVersion\ProfileList\" & si.ToString & "\")

Dim myval As String
myval = MyReg.GetValue("Guid")
MsgBox(myval.ToString) ' retuns GUID no errors

Dim guid As String
guid = myval

Dim MyReg2 As Microsoft.Win32.RegistryKey
MyReg2 = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, host.Text) _
    .OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid\")

MsgBox(MyReg2.ToString)
'myreg2.DeleteSubKey(guid)

现在我已经测试了同一级别的其他键:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification

它们都会返回值,但在尝试打开ProfileGuid时会抛出NullReferenceException。我可以完全访问远程注册表,并且我也在本地测试了相同的结果。我知道密钥存在。

他们是否可以直接删除它而无需打开子键?或者任何人都可以解释为什么它返回null?

1 个答案:

答案 0 :(得分:1)

您最有可能会遇到名为Registry Redirection的内容。

为了保持与32位应用程序的兼容性,64位版本的Windows实现了File System Redirector注册表重定向器。这两者的目的是保留一组独立的文件和注册表项(通常名称为WOW64),这些文件和注册表项仅限于32位应用程序。

例如,由于64位进程无法加载32位代码,因此仅使用32位版本的系统DLL和应用程序保留单独的系统目录。 32位系统目录的路径为%SystemRoot%\SysWOW64,而64位目录为标准%SystemRoot%\System32

这在注册表中的工作方式相同,但只有一组键具有相应的32位密钥。 32位密钥始终作为标准64位密钥的子密钥(例如HKLM\SOFTWARE),并称为Wow6432Node

文件系统重定向器(以及注册表重定向器)自动将所有32位应用程序重定向到相应的32位目录/注册表项,以确保32位应用程序仍在64-上运行比特系统。默认情况下,Visual Studio项目仅针对32位

据我所知,有两种方法可以解决这个问题:

  1. 将您的应用编译为AnyCPU而不是x86

    这是迄今为止最简单的解决方案。通过这样做,该应用程序将自动在32位系统上作为32位应用程序运行,或在64位系统上作为64位应用程序运行。因此,注册表重定向器不需要进行干预。

  2. 指定是否要访问注册表的32位视图或64位视图。

    .NET Framework具有内置功能,允许您指定是否要访问注册表的32位视图或64位视图。将其与Environment.Is64BitOperatingSystem相结合,以确定您要访问的视图。

    本地解决方案(针对其他人看到此问题):

    'Determine which registry view to use.
    Dim RegView As RegistryView = If(Environment.Is64BitOperatingSystem, RegistryView.Registry64, RegistryView.Registry32)
    
    'Opens HKEY_LOCAL_MACHINE with the specified registry view.
    Using RegHive As RegistryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegView)
    
        'Open the "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid" key.
        Using RegKey As RegistryKey = RegHive.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid", True)
            'Do stuff with the registry key...
        End Using
    End Using
    

    远程解决方案:

    (与上述相同,但更改了Using RegHive As RegistryKey行)

    Using RegHive As RegistryKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host.txt, RegView)