注册表虚拟化 是一种应用程序兼容性技术,使对全局影响注册表写入作能够重定向到每个用户的位置。 此重定向对于读取或写入注册表的应用程序是透明的。 从 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\Classes、HKEY_LOCAL_MACHINE\Software\Microsoft\Windows和 HKEY_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.
每当对正在虚拟化的密钥启用审核时,都会生成新的虚拟化审核事件,以指示密钥正在虚拟化(除了常规审核事件)。 管理员可以使用此信息来监视其系统上的虚拟化状态。
相关主题