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

NullReferenceException when opening a subkey I know exists

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

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)

现在测试了同级别的其他按键:

它们都是 return 值,但是当试图打开 ProfileGuid 时它会抛出一个 NullReferenceException。我拥有对远程注册表的完全访问权限,而且我还在本地进行了测试,结果相同。我知道密钥存在。

他们有什么办法可以直接删除它而不用打开子键吗?或者谁能​​解释为什么它是 returning null?

您很可能正在经历所谓的 Registry Redirection

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

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

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

文件系统重定向器(以及相应的注册表重定向器)自动将所有 32 位应用程序 重定向到相应的 32 位 directory/registry 键以确保 32- bit 应用程序仍然可以在 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)