打开我知道存在的子项时出现 NullReferenceException [英] NullReferenceException when opening a subkey I know exists

查看:68
本文介绍了打开我知道存在的子项时出现 NullReferenceException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试打开一个注册表项,以便我可以删除它的子项:

I'm trying to open a registry key so I can delete its subkeys:

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)

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

Now I have tested other keys on the same level:

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

它们都返回值,但是当试图打开 ProfileGuid 时它会抛出一个 NullReferenceException.我可以完全访问远程注册表,并且我还在本地对其进行了测试,结果相同.我知道密钥存在.

They all return values, but when trying to open ProfileGuid it throws a NullReferenceException. I have full access to the remote registry and I've also tested it locally with the same results. I know the key exists.

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

Is they any way I can delete it directly without opening subkeys? Or can anyone explain why it is returning null?

推荐答案

您很可能正在体验所谓的 注册表重定向.

You're most likely experiencing what's called Registry Redirection.

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

To maintain compatibility with 32-bit applications, 64-bit versions of Windows implemented the File System Redirector and the Registry Redirector. The purpose of these two is to keep a seperate set of files and registry keys (usually goes under the name WOW64) that are specific to 32-bit applications only.

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

For instance, due to that a 64-bit process cannot load 32-bit code, a separate system directory is kept with only 32-bit versions of the system DLLs and applications. The path to the 32-bit system directory is %SystemRoot%\SysWOW64, while the 64-bit directory is the standard %SystemRoot%\System32.

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

This works the same way in the registry, though only a certain set of keys have a respective 32-bit key. The 32-bit key is always located as a subkey of the standard 64-bit key (for example HKLM\SOFTWARE) and is called Wow6432Node.

文件系统重定向器(以及相应的注册表重定向器)自动重定向所有 32 位应用程序到相应的 32 位目录/注册表项,以确保 32 位应用程序仍然可以在 64-位系统.默认情况下,Visual Studio 项目面向 32 位.

The File System Redirector (and respectively the Registry Redirector) automatically redirects all 32-bit apps to the respective 32-bit directory/registry key to ensure that 32-bit apps still work on 64-bit systems. By default Visual Studio projects target 32-bit only.

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

As far as I know there are two ways to overcome this problem:

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

  1. Compile your app as AnyCPU instead of x86.

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

This is by far the most simple solution. By doing this the app will automatically run as a 32-bit app on a 32-bit system, or as a 64-bit app on a 64-bit system. Thus the Registry Redirector won't need to intervene.

指定您要访问注册表的 32 位视图还是 64 位视图.

.NET Framework 有一项内置功能,可让您指定是要访问注册表的 32 位视图还是 64 位视图.将其与 Environment.Is64BitOperatingSystem 以确定您要访问的视图.

The .NET Framework has a built in feature that lets you specify if you want to access the 32-bit view or the 64-bit view of the registry. Combine that with Environment.Is64BitOperatingSystem to determine which view you want to access.

本地解决方案(供其他人看到):

'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 行)

(same as above, but changed the Using RegHive As RegistryKey line)

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

这篇关于打开我知道存在的子项时出现 NullReferenceException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆