注册表虚拟化

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

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

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

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

虚拟化概述

在 Windows Vista 之前,应用程序通常由管理员运行。 因此,应用程序可以自由地访问系统文件和注册表项。 如果这些应用程序由标准用户运行,则它们会因为访问权限不足而失败。 Windows Vista 和更高版本的 Windows 通过自动重定向这些操作来提高这些应用程序的应用程序兼容性。 例如,对全局存储 (HKEY _ 本地 _ 计算机 \ 软件) 的注册表操作会重定向到用户配置文件中的每个用户位置,该位置称为 虚拟存储 (HKEY _ 用户 \ _ 类 \ VirtualStore \ 计算机 \ 软件) 。

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

打开注册表虚拟化

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

如果为 _ 键设置了注册表项 _ _ _ not 缄默 FAIL 标志,则操作将失败,并且不会打开该项。 有关详细信息,请参阅本主题后面的 "控制注册表虚拟化"。

写入注册表虚拟化

如果调用方对某个键没有写入访问权限,尝试向其写入值或创建一个子项,则会将该值写入虚拟存储区。

例如,如果某个受限用户尝试向以下键写入值: HKEY _ 本地 _ 计算机 \ software \ AppKey1,则虚拟化会将写入操作重定向到 HKEY _ USERS \ _ 类 \ VirtualStore \ MACHINE \ Software \ AppKey1

读取注册表虚拟化

如果调用方从虚拟化的密钥中进行读取,则注册表将显示虚拟化值的合并视图,这些值 (从虚拟存储) ,而非虚拟值 (从全局存储) 到调用方。

例如,假设 HKEY _ LOCAL _ MACHINE \ Software \ AppKey1 包含两个值 V1 和 V2,并且受限用户将值 V3 写入密钥。 当用户尝试读取此项的值时,合并视图将从该虚拟存储区中包含来自全局存储区的值 V1 和 V2 和值 V3。

请注意,在存在时,虚拟值优先于全局值。 在上面的示例中,即使全局存储在此项下具有值 V3,值 V3 仍将从虚拟存储返回到调用方。 如果要从虚拟存储中删除 V3,则会从全局存储中返回 V3。 换而言之,如果要从 HKEY _ 用户 \ _ 类 \ VirtualStore \ 计算机 \ 软件 \ AppKey1 ,但 HKEY _ 本地 _ 计算机 \ 软件 \ AppKey1 具有值 V3,则会从全局存储返回该值。

注册表虚拟化范围

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

  • 32位交互进程。
  • HKEY _ 本地 _ 计算机 \ 软件 中的密钥。
  • 管理员可以写入的键。 (如果管理员不能写入密钥,则应用程序将在以前版本的 Windows 上失败,即使是由管理员运行也是如此。 )

为以下项禁用了注册表虚拟化:

  • 64位进程。

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

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

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

  • 内核模式进程(如驱动程序)。

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

  • HKEY _ 本地 _ 计算机 \ software \ 类HKEY _ local _ machine \ SOFTWARE \ microsoft \ windowsHKEY _ local _ machine \ software \ microsoft \ windows NT 的注册表项和子项。

控制注册表虚拟化

除了通过使用清单中的 requestedExecutionLevel 在应用程序级别控制虚拟化之外,管理员还可以针对 HKEY _ 本地 _ 计算机 \ 软件 中的密钥,针对每个密钥启用或禁用虚拟化。 为此,请将 Reg.exe 命令行实用程序标志选项与下表中列出的标志一起使用。

标志 含义
注册表 _ 项 _ 不 _ 提示 _ 失败 此标志禁用打开的注册表虚拟化。 如果设置了此标志,并且启用虚拟化的密钥上的打开操作失败,则注册表将不会尝试重新打开该项。 如果此标志清晰,则注册表将尝试使用最大限度 _ 的访问权限(而不是所请求的访问权限)重新打开该密钥。
注册表 _ 项 _ 不 _ 虚拟化 此标志禁用写入注册表虚拟化。 如果设置了此标志,并且由于调用方没有足够的访问权限来访问父项,则 "创建项" 或 "设置值" 操作失败,注册表将使操作失败。 如果清除此标志,则注册表将尝试写入虚拟存储区中的键或值。 调用方必须具有 _ 父键的 "读取" 权限。
注册表 _ 项 _ 递归 _ 标志 如果设置了此标志,则将从父项传播注册表虚拟化标志。 如果清除此标志,则不会传播注册表虚拟化标志。 更改此标志将只影响在更改标志后创建的新的派生密钥。 它不会设置或清除现有的子代密钥的标志。

下面的示例演示如何使用带 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.

如果对要虚拟化的密钥启用了审核,则会生成一个新的虚拟化审核事件,以指示该密钥正在 (添加到常见审核事件) 。 管理员可以使用此信息监视其系统上虚拟化的状态。

入门与用户帐户控制

了解和配置用户帐户控制

最小特权环境中应用程序的开发人员最佳实践和指南