为什么注册表写在不同于预期的位置?

我尝试将注册表子项及其对应的值写入注册表,如下所示:

const string subKey = @"SOFTWARE\Apple\Banana\"; const string regKey = "pip"; var rk = Registry.LocalMachine.OpenSubKey(subKey); if (rk == null) rk = Registry.LocalMachine.CreateSubKey(subKey); var rv = rk.GetValue(regKey); if (rv == null) rk.SetValue(regKey, "XXX"); return rv.ToString(); 

现在的问题是,当我手动查看位置(通过注册表)时,我无法在HKLM看到文件夹SOFTWARE\Apple\Banana

但是当我再次运行上面的代码并进行调试时,我可以看到Registry.LocalMachine.OpenSubKey(subKey)rk.GetValue(regKey)产生之前保存的值。 然而,我没有通过regedit看到给定位置的值。 所以在搜索注册表时,我可以在以下位置看到上面的键和值:

  1. HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Apple\Banana

  2. HKEY_USERS\S-1-5-21-44266131-1313801407-2392705078-1000\Software\Classes\VirtualStore\MACHINE\SOFTWARE\Apple\Banana

在两者之下,价值保持与我保存完全一样。 所以我意识到这是我的应用程序读取值的地方虽然在我的代码中我从HKLM\SOFTWARE\Apple\Banana\调用它。

  1. 为什么会这样? 它与访问权限问题有关吗?

  2. 这是预期的行为吗? 从某种意义上说,这个值对我来说非常重要,所以我只知道是否存在与自动重定位相关的风险!

  3. 是否有正确的方式写入注册表,以便它保持在其确切的位置..

我的帐户是管理员一,我使用的是32位Windows 7。

编辑:据我所知,注册表项存储在当前用户位置而不是HKLM中。 当我从另一个帐户查询reg值时,我没有得到该值。 简而言之,首先将它保存到HKLM没有意义:(

是的,这是正确的行为并且它正在发生,因为您没有足够的权限直接写入HKLM配置单元。 它被称为虚拟化,也适用于文件系统,自Vista以来,它一直是操作系统中的一种行为。

您应该按原样继续并尝试从您正在写入的相同HKLM密钥中读取,Windows将透明地为您重定向。

Preet已经提供了一个MSDN链接,您应该仔细阅读。

请注意,当您访问HKLM下的密钥时,即使您以管理员身份运行,也应该包括所需的权限(因为密钥不会自动以管理员权限打开,您必须请求它):

 key = key.OpenSubKey(keyname, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl); 
  1. 这是Registry Virtualization(msdn)

    注册表虚拟化是一种应用程序兼容性技术,可以将具有全局影响的注册表写入操作重定向到每个用户的位置。 此重定向对于从注册表读取或写入注册表的应用程序是透明的。 从Windows Vista开始支持它。

    虚拟化概述

    在Windows Vista之前,应用程序通常由管理员运行。 因此,应用程序可以自由访问系统文件和注册表项。 如果这些应用程序由标准用户运行,则由于访问权限不足而导致其失败。 Windows Vista和更高版本的Windows通过自动重定向这些操作来提高这些应用程序的应用程序兼容性。 例如,对全局存储(HKEY_LOCAL_MACHINE \ Software)的注册表操作将重定向到用户配置文件中称为虚拟存储(HKEY_USERS \ _Classes \ VirtualStore \ Machine \ Software)的每用户位置。

  2. 是的,它应该是应有的。

  3. 如果要写入全局影响位置,请使用虚拟化,或者如果不需要,请使用更多本地化位置。 无论哪种方式,它对读者都是不可见的,所以不要担心它。