注册表虚拟化

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

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

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

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

虚拟化概述

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

注册表虚拟化可大致分为以下类型:

打开注册表虚拟化

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

如果为密钥设置了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> 中删除 V3_Classes\VirtualStore\Machine\Software\AppKey1 ,但 HKEY_LOCAL_MACHINE\Software\AppKey1 具有值 V3,则将从全局存储返回该值。

注册表虚拟化范围

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

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

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

  • 64 位进程。

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

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

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

  • 驱动程序等内核模式进程。

  • 在其清单中指定的 requestedExecutionLevel 的进程。

  • 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.

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

使用用户帐户控制入门

了解和配置用户帐户控制

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