Registry Virtualization

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

这种形式的虚拟化是一种临时应用程序兼容性技术;Microsoft打算将其从 Windows作系统的未来版本中删除,因为更多的应用程序与 Windows Vista 和更高版本的 Windows 兼容。 因此,应用程序并不依赖于系统中注册表虚拟化的行为,这一点很重要。

虚拟化仅用于为现有应用程序提供兼容性。 专为 Windows Vista 和更高版本的 Windows 设计的应用程序不应写入敏感系统区域,也不应依赖虚拟化来纠正任何问题。 更新现有代码以在 Windows Vista 和更高版本的 Windows 上运行时,开发人员应确保应用程序仅将数据存储在每用户位置或 %alluserprofile% 的计算机位置中,这些位置正确使用访问控制列表(ACL)。

有关生成符合 UAC 的应用程序的详细信息,请参阅 UAC 开发人员指南

虚拟化概述

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

注册表虚拟化可以广泛分类为以下类型:

Open Registry Virtualization

如果调用方没有对密钥的写入访问权限并尝试打开密钥,则会打开该密钥,该调用方允许的最大访问权限。

如果为密钥设置了REG_KEY_DONT_SILENT_FAIL标志,作将失败,并且未打开密钥。 有关详细信息,请参阅本主题后面的“控制注册表虚拟化”。

写入注册表虚拟化

如果调用方没有对密钥的写入访问权限,并且尝试向其写入值或创建子项,则该值将写入虚拟存储。

例如,如果受限用户尝试将值写入以下键:HKEY_LOCAL_MACHINE\Software\AppKey1,虚拟化会将写入作重定向到 HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\AppKey1

读取注册表虚拟化

如果调用方从虚拟化的键读取,注册表会将虚拟化值(从虚拟存储)和非虚拟值(从全局存储)合并视图呈现给调用方。

例如,假设 HKEY_LOCAL_MACHINE\Software\AppKey1 包含两个值 V1 和 V2,并且有限用户将值 V3 写入密钥。 当用户尝试从此键读取值时,合并的视图包括全局存储中的值 V1 和 V2,以及虚拟存储中的值 V3。

请注意,当存在时,虚拟值优先于全局值。 在上面的示例中,即使全局存储在此键下有值 V3,值 V3 仍将从虚拟存储返回到调用方。 如果要从虚拟存储中删除 V3,则会从全局存储返回 V3。 换句话说,如果要从 HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\AppKey1 中删除 V3,但 HKEY_LOCAL_MACHINE\Software\AppKey1 具有值 V3,则该值将从全局存储返回。

注册表虚拟化范围

注册表虚拟化仅针对以下项启用:

  • 32 位交互式进程。
  • HKEY_LOCAL_MACHINE\Software中的键。
  • 管理员可以写入的密钥。 (如果管理员无法写入密钥,则即使应用程序由管理员运行,应用程序也会在早期版本的 Windows 上失败。

注册表虚拟化已禁用以下各项:

  • 64 位进程。

  • 非交互式进程,例如服务。

    请注意,将注册表用作服务(或未启用虚拟化的任何其他进程)之间的进程间通信(IPC)机制,如果密钥虚拟化,应用程序将无法正常工作。 例如,如果防病毒服务根据应用程序设置的值更新其签名文件,该服务永远不会更新其签名文件,因为服务从全局存储读取,但应用程序会写入虚拟存储。

  • 模拟用户的进程。 如果进程在模拟用户时尝试某个作,则不会虚拟化该作。

  • 内核模式进程,例如驱动程序。

  • 请求的ExecutionLevel 在其清单中指定的进程。

  • HKEY_LOCAL_MACHINE\Software\ClassesHKEY_LOCAL_MACHINE\Software\Microsoft\WindowsHKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT的键和子项。

控制注册表虚拟化

除了在清单中使用 requestedExecutionLevel 来控制应用程序级别的虚拟化之外,管理员还可以在 HKEY_LOCAL_MACHINE\Software中的密钥按密钥启用或禁用虚拟化。 为此,请使用 Reg.exe 命令行实用工具 FLAGS 选项和下表中列出的标志。

意义
REG_KEY_DONT_SILENT_FAIL 此标志禁用打开的注册表虚拟化。 如果设置了此标志,并且打开作在启用了虚拟化的密钥上失败,则注册表不会尝试重新打开密钥。 如果此标志明确,注册表会尝试重新打开具有MAXIMUM_ALLOWED访问权限的密钥,而不是请求的访问。
REG_KEY_DONT_VIRTUALIZE 此标志禁用写入注册表虚拟化。 如果设置了此标志,并且创建密钥或设置值作失败,因为调用方对父密钥没有足够的访问权限,则注册表将失败该作。 如果此标志明确,注册表将尝试在虚拟存储中写入密钥或值。 调用方必须在父密钥上具有KEY_READ。
REG_KEY_RECURSE_FLAG 如果设置了此标志,注册表虚拟化标志将从父密钥传播。 如果此标志明确,则不会传播注册表虚拟化标志。 更改此标志仅影响更改标志后创建的新后代键。 它不会为现有后代键设置或清除这些标志。

 

以下示例演示如何使用具有 FLAGS 选项的 Reg.exe 命令行实用工具来查询密钥的虚拟化标志的状态。

C:\>reg flags HKLM\Software\AppKey1 QUERY

HKEY_LOCAL_MACHINE\Software\AppKey1

        REG_KEY_DONT_VIRTUALIZE: CLEAR
        REG_KEY_DONT_SILENT_FAIL: CLEAR
        REG_KEY_RECURSE_FLAG: CLEAR

The operation completed successfully.

每当对正在虚拟化的密钥启用审核时,都会生成新的虚拟化审核事件,以指示密钥正在虚拟化(除了常规审核事件)。 管理员可以使用此信息来监视其系统上的虚拟化状态。

用户帐户控制入门

了解和配置用户帐户控制

最低特权环境中应用程序的开发人员最佳做法和指南