打开我知道存在的子项时出现 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)
现在测试了同级别的其他按键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification
它们都是 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 位 .
据我所知有两种方法可以解决这个问题:
将您的应用程序编译为 AnyCPU
而不是 x86
。
这是迄今为止最简单的解决方案。通过这样做,该应用程序将自动 运行 作为 32 位系统上的 32 位应用程序,或作为 64 位系统上的 64 位应用程序。因此注册表重定向器不需要干预。
指定是要访问注册表的 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)
我正在尝试打开注册表项以便删除其子项:
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
它们都是 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 位 .
据我所知有两种方法可以解决这个问题:
将您的应用程序编译为
AnyCPU
而不是x86
。这是迄今为止最简单的解决方案。通过这样做,该应用程序将自动 运行 作为 32 位系统上的 32 位应用程序,或作为 64 位系统上的 64 位应用程序。因此注册表重定向器不需要干预。
指定是要访问注册表的 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)