灵活虚拟化

概述

灵活的虚拟化功能使应用能够声明其某一组文件和注册表条目对其他应用可见;并且这些应用应在卸载应用时保留。 所有其他文件和注册表项对其他应用不可见;卸载时会将其删除

如何控制所选位置的虚拟化

注意

本部分中所述的行为在 Windows 10 版本 21H1 中引入。

从 Windows 10 版本 21H1 开始,系统保留 unvirtualizedResources 受限功能的现有行为,以及 RegistryWriteVirtualizationFilesystemWriteVirtualization 属性。 此外,系统还新增了应用声明要取消虚拟化的特定文件夹和/或注册表项的功能。

  • 只能声明 %USERPROFILE%\AppData 中的文件系统位置。
  • 只能声明 HKCU 中的注册表位置

下面是一个示例。

<!-- Declare the desktop6 and/or virtualization XML namespace where the virtualization properties are defined, and include this in the list of ignorable namespaces. -->
<!-- Declare the XML namespace for the required restricted capability, and include it in the list of ignorable namespaces. -->
<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10"
  IgnorableNamespaces="rescap desktop6 virtualization">

  <!-- ... -->
  <!-- Other entries omitted for brevity. -->
  <!-- ... -->

  <Properties>
    <!-- If you don't want virtualization of registry writes to HKEY_CURRENT_USER, then include the property, and set it to disabled. -->
    <desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>

    <!-- If you don't want virtualization of file system writes to the user's AppData folder, then include the property, and set it to disabled. -->
    <desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>
    
    <!-- On Windows 10, version 21H1 and later OS versions, you can declare specific file system and/or registry locations that you want to be unvirtualized. 
    If these are recognized on the current device, then they take precedence over the old declarations. On older devices,
    the new declarations are ignored and the old ones are honored. -->
    <virtualization:FileSystemWriteVirtualization>
      <virtualization:ExcludedDirectories>
        <virtualization:ExcludedDirectory>$(KnownFolder:LocalAppData)\Fabrikam\Widgets</virtualization:ExcludedDirectory>
        <virtualization:ExcludedDirectory>$(KnownFolder:RoamingAppData)\Fabrikam\Widgets</virtualization:ExcludedDirectory>
      </virtualization:ExcludedDirectories>
    </virtualization:FileSystemWriteVirtualization>

    <virtualization:RegistryWriteVirtualization>
      <virtualization:ExcludedKeys>
        <virtualization:ExcludedKey>HKEY_CURRENT_USER\Software\Fabrikam\Widgets</virtualization:ExcludedKey>
      </virtualization:ExcludedKeys>
    </virtualization:RegistryWriteVirtualization>
  </Properties>

  <Capabilities>
    <!-- Include the required restricted capability. -->
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
</Package>

注意

如果应用同时声明 Windows 10 版本 21H1 之前的版本和 Windows 10 版本 21H1 语法,则旧声明将用于 Windows 10 版本 21H1 之前的版本,而新声明将用于 Windows 10 版本 21H1 之前的版本以及更高版本。

Windows 10 版本 21H1 之前的机制

在传统环境中,应用可以在文件系统中的大多数位置创建、更新和删除文件。 他们可以创建、更新和删除 Windows 注册表中的条目。 这些文件和注册表条目对系统上的其他应用可见,即使通常没有这种需要。 此外,卸载应用时,这些文件和注册表项通常会留下,变得混乱。

在通用 Windows 平台 (UWP) 中,此类文件和注册表条目已虚拟化,以便仅撰写它们的应用才拥有其可见性。 卸载应用时,便会将其删除。 但在某些情况下,应用希望此类文件和注册表条目对其他应用可见。 此外,其他应用可能要求此类文件和条目即使在卸载了撰写这些文件和条目的应用后仍然存在。

默认 MSIX 行为

位置 上下文 说明
HKCU 安装时间
  • 该应用可包含一个 user.dat 文件,该文件指定 HKCU\Software 条目。 这些条目实际上会写入用户的“AppData”文件夹(位于每个应用的子文件夹)中的 user.dat 文件,并呈现给应用,就好像密钥位于 HKCU 中一样
  • 针对读取,此专用配置单元与未虚拟化的 HKCU\Software 合并,以便所有条目看起来都位于同一位置
  • 卸载应用后,虚拟化条目将不再可用,因为它们从未实际添加到注册表中。
  • 虚拟化配置单元中的密钥仅对应用可见。
HKCU 运行时间
  • 写入会转到单独的每应用、每用户专用配置单元。
  • 针对读取,此配置单元与未虚拟化的 HKCU 合并,以便所有条目看起来都位于同一位置。
  • 卸载应用时,将删除虚拟化条目。
  • 虚拟化配置单元中的密钥仅对应用可见。
HKLM 安装时间
  • 该应用可包含一个 registry.dat 文件,该文件指定 HKLM\Software 条目。 这些条目实际上会写入用户的“AppData”文件夹(位于每个应用的子文件夹)中的 user.dat 文件,并呈现给应用,就好像密钥位于 HKLM 中一样
  • 针对读取,此专用配置单元与未虚拟化的 HKLM\Software 合并,以便所有条目看起来都位于同一位置
  • 卸载应用后,虚拟化条目将不再可用,因为它们从未实际添加到注册表中。
  • 虚拟化配置单元中的密钥仅对应用可见。
HKLM 运行时间
  • 只要包配置单元中不存在相应的键/值,并且用户具有正确的访问权限,便允许 HKLM 下的写入(这实际上意味着这仅适用于运行提升的 Centennial 应用)
已知文件夹 安装时间
  • 该应用可包含一个 VFS 文件夹,其中具有含任意文件的已知命名子文件夹
  • 针对读取,这些子文件夹与未虚拟化的已知位置合并,以便所有文件看起来都位于同一位置。
AppData 运行时间
  • 对于低于或等于 1809 的 Windows 版本,对用户的“AppData”文件夹的所有写入(包括创建、删除和更新)都将在写入时复制到特定于用户和应用的专用位置,该位置将在运行时合并,以在实际 AppData 位置中显示
  • 若 Windows 版本高于 1809,则用户的“AppData”文件夹中所有新建的文件和文件夹都将写入特定于用户和应用的专用位置,但在运行时将会合并,以在实际的 AppData 位置显示。 对现有 AppData 文件的修改在未虚拟化的文件上完成。 针对读取,系统首先尝试专用位置,然后返回到未虚拟化的 AppData
  • 回退时,允许写入未虚拟化的文件。
  • 卸载应用时,将删除虚拟化条目。
  • 虚拟化位置中的文件仅对应用可见。
  • AppData 不提供 VFS 支持
  • 除了 AppData,应用可以写入用户具有写入权限的任何位置,包括 %userprofile% 的其他部分(AppData 只是其中的一部分)

unvirtualizedResources 受限功能

注意

Windows 10 版本 1903(10.0;内部版本 18362)中引入了对 unvirtualizedResources 受限功能的支持,也称为 Windows 2019 年 5 月 10 日更新。

应用可以声明 unvirtualizedResources 受限功能,并将 RegistryWriteVirtualization 和/或 FilesystemWriteVirtualization 属性设置为 true,以获得对 HKCU 和/或 AppData 的写入访问权限。 这是为了支持以下情况:应用需要编写随后对包外部的其他进程可见的条目。 例如,游戏将保存数据写入 AppData,即使卸载游戏,该数据也需要持久保存

properties 说明
RegistryWriteVirtualization=disabled 对 HKCU 的写入会转到未虚拟化的位置,对包外部的其他进程可见,并且在卸载应用时不会清理
FilesystemWriteVirtualization=disabled 对 AppData 的写入会转到未虚拟化的位置,对包外部的其他进程可见,并且在卸载应用时不会清理

此机制会将 HKCU 和/或 AppData 虚拟化全一并关闭,这与主要目标背道而驰。 这并不是一种精细的工具,经常超过给定应用的要求。