MSIX 框架包和动态依赖项

本文介绍与 MSIX 框架包相关的重要概念。 本文中的信息可提供有用的上下文,帮助更好地了解 Windows 应用 SDK 和 Windows 11 OS 中动态依赖项功能的设计和用途。 此功能使应用可以在运行时引用和使用 .MSIX 框架包。

框架包和包图

MSIX 是一种包格式,可提供现代打包和部署体验。 它还通过 MSIX 框架包提供一种干净可靠的方式来打包可再发行库、内容和组件。 MSIX 框架包使 MSIX 打包的应用可以通过用户设备上的单一共享源来访问组件,而不是将组件绑定到应用包。 常见框架包包括 Windows 应用 SDK(包括 WinUI3)、WinUI2VCLibs 和 DirectX 运行时。

从 Windows 8 开始,一直到 Windows 10 和 Windows 11,每个进程都有一个包图,它提供应用可用的所有包的列表(包括框架包、资源包、可选包和主包)。 此图使应用可以加载所引用包提供的 DLL、内容和运行时类声明。 过去,此图在创建进程时进行固定,无法在运行时进行更改:

  • 对于 MSIX 打包的应用,此图基于在应用包清单的 PackageDependency 元素中声明的包依赖项进行初始化。 生成打包的应用时,通常会基于项目引用和依赖项在生成过程中完成此操作。
  • 对于未打包的应用(即,不将 MSIX 用于其部署技术的应用),包图为空,无法更改。 因此,未打包的应用限制为标准 DLL 搜索顺序,无法访问框架包。

随着在 Windows 应用 SDK 和 Windows 11 中引入动态依赖项支持,此静态包图限制已解除。 开发人员可以使用动态依赖项在运行时,从其应用中引用和使用 MSIX 框架包。 动态依赖项从应用中消除了静态包图限制,开发人员可以决定要如何利用框架包。

动态依赖项的主要方案

尽管动态依赖项使任何应用都可以在运行时添加包框架依赖项,但此功能主要旨在由未打包的应用所使用。 打包的应用仍可继续通过其包清单中的 PackageDependency 元素添加静态依赖项。

  • 大多数开发人员会只使用动态依赖项在未打包的应用中引用 Windows 应用 SDK 框架包,以便应用可以调用 Windows 应用 SDK 运行时提供的 API。 有关此场景的详细信息,请参阅使用 Windows 应用 SDK 运行时
  • 在某些情况下,开发人员可能希望使用动态依赖项从未打包的应用引用其他框架包(非 Windows 应用 SDK 框架包,例如 WinUI2 或 DirectX 运行时的框架包)。 有关此方案的详细信息,请参阅 在运行时引用框架包

框架包的服务模型

动态依赖项功能会保留在运行时动态引用并使用的框架包的服务管道的完整性。

MSIX 框架包支持采用并行模型的服务,这意味着每个版本都安装在其自己的单独版本控制文件夹中。 这样,即使较新的应用安装了较新版本的框架包,所使用的应用程序仍可以保持正常运行。 对于何时删除给定框架包的旧版本,操作系统具有基于是否存在包的安装时引用和运行时引用的卸载逻辑 。

  • 安装应用时,它可以创建对框架包的安装时引用。 此引用会向操作系统告知应用依赖于指定框架包,以便在安装应用时,操作系统不会卸载该框架包。
  • 应用需要使用框架包中的 API 或内容时,它可以添加对框架包的运行时引用。 此引用会向操作系统告知框架包处于活动使用状态,以按并行方法处理任何版本更新。 如果安装新版本的框架包,但正在运行的应用使用了较旧版本,则在删除对较旧版本的所有运行时引用之前,操作系统无法删除较旧版本。

例如,对于以下方案:

  • 应用 A 正在运行并使用给定框架包的版本 1.0.0.0。
  • 应用 B 进行安装,并依赖于相同框架包的版本 1.0.0.1。

在此方案中,框架包的两个版本都会进行安装并由应用 A 和 应用 B 安装使用。但是,当应用 A 由用户关闭,然后重新启动时,它会选取框架包的较新版本 1.0.0.1 。 此时,运行时引用要求不再对框架包的版本 1.0.0.0 有效,操作系统可以安全地删除版本 1.0.0.0。 稍后,当用户卸载应用 A 和应用 B 时,安装时引用要求将不再有效,操作系统可以安全地完全删除框架包 。

对于使用 PackageDependency 元素指定对框架包的静态引用的 MSIX 打包应用程序,在安装或卸载应用时,操作系统会跟踪框架包的安装时引用。 对于使用动态依赖项功能进行管理的运行时引用,操作系统知道打包的应用正在运行,在有较新框架包可用时,会避免删除其所使用的框架包。