总体迁移策略

介绍

Windows App SDK 提供了各种 Windows API,其实现与操作系统分离,并通过 NuGet 包发布给开发人员。 作为使用通用 Windows 平台 (UWP) 应用程序的开发人员,可以通过将应用移动到 Windows App SDK 来充分利用现有技能集和源代码。

借助 Windows App SDK,可以将最新的运行时、语言和平台功能合并到应用中。 由于每个应用程序都不同,要求和偏好也不同,因此有许多不同的方法来迁移应用的源代码。 但是,高级方法以及各种功能区域所需的代码更改是类似的。 因此,在本主题中,我们将回顾迁移应用的策略,以及有关某些功能区域的详细信息(及限制)。 因此,另请参阅从 UWP 移植到 WinUI 3 时支持的功能

大多数 Windows 运行时 (WinRT) API 都可用于 Windows App SDK 应用。 但有一些在桌面应用中不受支持或存在限制。

  • 依赖于 UI 功能的 API,这些功能仅在 UWP 应用中可用。
  • 需要包标识的 API。 这些 API 仅在使用 MSIX 打包的桌面应用中受支持。

对于这些 API,我们将展示要使用的替代方法。 大多数替代 API 都是通过 WinUI 或通过 Windows App SDK 中的 WinRT COM 接口提供的。

例如,我们将看到某些 UI 方案,需要跟踪主窗口对象,并使用各种基于“HWND”的 API 和互操作模式,例如 IInitializeWithWindow::Initialize

注意

另请参阅桌面应用中不支持的 Windows 运行时 API。 Windows App SDK 应用是一种桌面应用。 其他类型的桌面应用包括 .NET 桌面应用和 C/C++ Win32 桌面应用。 该主题的受众是希望迁移到这些不同类型的桌面应用(包括但不限于 Windows App SDK 应用)联合的任何内容的开发人员。

我们很想了解你对本迁移指南的反馈,以及你自己的迁移体验。 使用本页底部的“反馈”部分,如下所示:

  • 有关 Windows App SDK 的问题和反馈,或者开启讨论,请使用“此产品”按钮。 此外,还可在 WindowsAppSDK GitHub 存储库的“讨论”选项卡中发起讨论。 使用这些渠道,还可以告诉我们要尝试解决什么问题、到目前为止如何尝试解决该问题,以及什么是应用的理想解决方案。
  • 有关此迁移指南中缺失或不正确的信息的反馈,请使用“此页面”按钮。

为什么要迁移到 Windows App SDK?

Windows App SDK 提供了机会,可以使用新的平台功能以及现代 Windows UI 3 库 (WinUI 3) 来增强应用,其开发和设计旨在让用户满意。

此外,Windows App SDK 向后兼容;它最低支持 Windows 10 版本 1809(10.0,内部版本 17763)应用,也称为 Windows 10 2018 年 10 月更新。

移动 Windows App SDK 的价值主张是多方面的。 下面是一些注意事项:

  • 最新的用户界面(UI)平台和控件,如 WinUI 3 和 WebView2
  • 在不同的桌面应用平台中实现统一的 API 图面。
  • 更频繁的发布节奏,与 Windows 分开发布。
  • 在多个 Windows 版本中实现一致体验。
  • .NET 兼容性。
  • 向后兼容到 Windows 10 版本 1809。
  • 改进运行时环境。 请参阅 MSIX 容器

有关详细信息,请参阅 Windows App SDK

迁移过程概述

注意

可以将要迁移的应用的 UWP 版本视为解决方案/项目(其为迁移过程的)。 Windows App SDK 版本是目标解决方案(指迁移过程的目标)。

安装 Windows App SDK VSIX

Windows App SDK 的稳定发布渠道下载 Windows App SDK Visual Studio 扩展 (VSIX) 安装器,然后运行以安装。

创建新项目

在 Visual Studio 中,创建第一个 WinUI 3 项目。 例如,使用打包的空白应用(桌面版 WinUI 3)项目模板。 可以在“创建新项目”对话框中找到该项目模板,方法是选择语言:C#C++;平台:Windows App SDK;项目类型:WinUI桌面

在“解决方案资源管理器”中会看到两个项目——一个项目限定为“桌面”,另一个限定为“包”。

首先迁移依赖项最少的代码

为了说明此建议,让我们以 PhotoLab 案例研究为例。 对于 PhotoLab 示例应用,一种显而易见的方法是先迁移“MainPage”,因为这是应用重要且突出的一部分。 但如果要这样做,我们很快就会意识到“MainPage”依赖于“DetailPage”视图;以及,“DetailPage”依赖于“照片”模型。 如果我们遵循该路径,则可能会一直打断自己(切换到处理每个新发现的依赖关系)。 当然,在追踪每个依赖项并实质上以一次巨大的跨越移植整个项目之前,我们并不期望获得干净的生成

另一方面,如果我们从不依赖于任何其他内容的项目部分开始,然后逐渐开展工作(从依赖程度最低的部分到依赖程度最高的部分),那么我们每次都能够专注于一个部分。 我们还能够在迁移每个部分后实现干净生成,并以这种方式确认迁移过程是否保持正常。

因此,在迁移自己的应用时,建议首先迁移依赖项最少的代码。

复制文件,还是复制文件内容?

迁移时,当然会复制资产文件(而不是资产文件内容)。 但是,源代码文件呢? 例如,让我们再次从 PhotoLab 案例研究照片编辑器案例研究中获取 MainPage 类。

C# 中的检测示例。 在 C# 版本 (PhotoLab) 中,“MainPage”由源代码文件 MainPage.xamlMainPage.xaml.cs 组成。

C++/WinRT。 在 C++/WinRT 版本(照片编辑器)中,“MainPage”由源代码文件 MainPage.xamlMainPage.idlMainPage.hMainPage.cpp 组成。

因此,可以选择以下两个选项:

  • (建议)可以复制文件本身(使用“文件资源管理器”),然后将副本添加到目标项目中。 此建议中的例外情况是 App.xamlApp.xaml.cs 等文件,因为它们已存在于目标项目中,并且包含特定于 Windows App SDK 的源代码。 对于这些项,需要将已经存在的源代码与源项目中的源代码合并
  • 或者,可以使用 Visual Studio 在目标项目中创建新的“页”文件(例如 MainPage.xamlMainPage.xaml.cs),然后将这些源代码文件的内容从源项目复制到目标项目。 对于 C++/WinRT 项目,此选项涉及更多步骤。

另请参阅 MainPage 和 MainWindow 部分。

文件夹和文件名差异 (C++/WinRT)

在 C++/WinRT UWP 项目中,XAML 视图的代码隐藏文件以 MainPage.hMainPage.cpp 的形式命名。 但在 C++/WinRT Windows App SDK 中,需要将名称重命名为 MainPage.xaml.hMainPage.xaml.cpp

在 C++/WinRT UWP 项目中,在迁移名为“MyPage”的假设 XAML 视图(在模型、视图和视图模型层面上)时,需要在 MyPage.xaml.cpp#include "DetailPage.xaml.h" 之后立即添加 #include "MyPage.g.cpp"。 对于名为“MyModel”的假设模型,在 MyModel.cpp 中 #include "MyModel.h" 之后立即添加 #include "MyModel.g.cpp"。 有关示例,请参阅迁移 DetailPage 源代码

如果更改已迁移项目的名称

迁移时,可以选择为目标项目指定与源项目不同的名称。 如果这样做,则会影响源项目中的默认命名空间。 将源代码从源项目复制到目标项目时,可能需要更改源代码中提到的命名空间名称。

我们要更改项目名称(以及默认的命名空间名称),例如案例研究 Windows App SDK 迁移 UWP PhotoLab 示例应用 (C#)。 在该案例研究中,我们使用文件资源管理器复制整个文件,而不是将文件内容从源项目复制到目标项目。 源项目/命名空间名称为 PhotoLab,目标项目/命名空间名称为 PhotoLabWinUI3。 因此,我们需要在复制的任何源代码文件的内容中搜索 PhotoLab,并将其更改为 PhotoLabWinUI3

在这一特定案例研究中,我们在App.xamlApp.xaml.csMainPage.xamlMainPage.xaml.csDetailPage.xamlDetailPage.xaml.csImageFileInfo.csLoadedImageBrush.cs中进行了以下更改。

安装源项目中安装的相同 NuGet 包

迁移过程中的一项任务是标识源项目依赖的任何 NuGet 包。 然后在目标项目中安装相同的 NuGet 包。

例如,在案例研究 Windows App SDK 迁移 UWP PhotoLab 示例应用 (C#)中,源项目包含对“Microsoft.Graphics.Win2D”NuGet 包的引用。 因此,在该案例研究中,我们将对同一 NuGet 包的引用添加到目标项目。