使用 .NET 升级助手从 UWP 迁移到 Windows 应用 SDK

.NET 升级助手(请参阅 .NET 升级助手概述)是 Visual Studio 扩展(推荐),也是一种命令行工具,可帮助将 C# 通用 Windows 平台 (UWP) 应用迁移到使用 Windows 应用 SDK 的 Windows UI 库 (WinUI) 3 应用。

.NET 升级助手中 UWP 支持的路线图包括进一步的工具改进,并添加对新功能的迁移支持。 如果发现与 .NET 升级助手相关的问题,可以通过选择“帮助”>“发送反馈”>“报告问题”在 Visual Studio 中提出这些问题

另请参阅升级助手 GitHub 存储库。 命令行上用于运行该工具的选项记录在该处。

安装 .NET 升级助手

可以将 .NET 升级助手安装为 Visual Studio 扩展或 .NET 命令行工具。 有关详细信息,请参阅安装 .NET 升级助手

总结

使用 .NET 升级助手迁移 UWP 应用时,该工具执行的迁移过程中的大致步骤和阶段如下。

  • (可选)复制项目并迁移副本;原始项目保持不变。
  • (可选)就地迁移项目(在相同文件夹和文件中,无需重命名文件夹);不创建副本。
  • 将项目从 .NET Framework 项目格式升级到最新的 .NET SDK 项目格式。
  • 清理 NuGet 包引用。 除了你的应用引用的包,packages.config 文件还包含对这些包的依赖项的引用。 例如,如果添加了对包 A 的引用,而该包依赖于包 B,则这两个包都将在 packages.config 文件中引用。 在新的项目系统中,只需要对包 A 的引用。 因此,此步骤分析包引用并删除不需要的包引用。 你的应用仍在引用 .NET Framework 程序集。 其中一些程序集可能作为 NuGet 包提供。 因此,此步骤会分析这些程序集并引用适当的 NuGet 包。
  • 面向 .NET 6 和 Windows 应用 SDK。
  • 将目标框架名字对象 (TFM)(请参阅 SDK 样式项目中的目标框架)从 .NET Framework 更改为建议的 SDK。 例如 net6.0-windows
  • 将 UWP 源代码从 WinUI 2 迁移到 WinUI 3,并执行特定于源代码的代码更改。
  • 添加/更新任何模板、配置和代码文件。 例如,添加必要的发布配置文件 App.xaml.csMainWindow.xaml.csMainWindow.xaml 等。
  • 更新命名空间,并添加 MainPage 导航
  • 尝试检测和修复 UWP 与 Windows 应用 SDK 之间不同的 API,并使用“任务列表”TODO 来标记不再受支持的 API

在运行时,该工具还旨在以警告消息的形式(在工具的输出中)提供迁移指导,并以注释的形式(在项目的源代码中)提供“任务列表”TODO(例如,对于无法完全自动迁移 UWP 源代码的情况)。 典型的“任务列表”TODO 包含指向此迁移文档中某个主题的链接。 开发人员始终可以控制迁移过程。

提示

若要查看该工具生成的所有待办事项 (TODO),请查看 Visual Studio 中的“任务列表”

注意

工具运行完成后,如果需要,可以选择执行一些后续步骤。 可以将代码从 App.xaml.old.cs 移动到 App.xaml.cs;也可以从该工具创建的备份还原 AssemblyInfo.cs

工具支持的功能

此版本的 .NET 升级助手目前为预览版,还在进行不断的更新。 该工具目前仅支持 C# 编程语言,不支持 C++。 在大多数情况下,使用此版本时,需要对项目执行其他操作才能完成迁移。

该工具旨在迁移项目和代码,以便进行编译。 但是,某些功能需要进行调查和修复(通过“任务列表”TODO)。 有关迁移之前需要考虑的事项的详细信息,请参阅从 UWP 迁移到 WinUI 3 时支持的功能

由于当前版本的 .NET 升级助手存在以下限制,可以选择等待更高版本发布后再迁移:

如果可能,该工具会尝试生成警告;它会故意不编译你的代码,直至你进行更改。

  • 不支持自定义视图。 例如,对于扩展 MessageDialog 和错误调用 API 的自定义对话框,你将不会收到警告或修复
  • 不支持 Windows 运行时组件。
  • 多窗口应用可能无法正确迁移。
  • 遵循非标准文件结构的项目(例如,不在根文件夹中的 App.xamlApp.xaml.cs)可能无法正确迁移。

升级助手 GitHub 存储库记录了故障排除提示和已知问题。 如果在使用该工具时发现任何问题,请在同一 GitHub 存储库中报告这些问题,并用区域标记 UWP 进行标记。 我们非常感谢!

注意

有关迁移过程的指导以及 UWP 与 Windows 应用 SDK 功能和 API 之间的差异,请参阅从 UWP 迁移到 Windows 应用 SDK

提示

可以通过发出命令 upgrade-assistant --version 来查看现有工具的版本。

使用 UWP PhotoLab 示例体验该工具

让我们来体验一下 .NET 升级助手。

作为源材料,我们将要迁移 UWP PhotoLab 示例应用程序。 PhotoLab 是用于查看和编辑图像文件的示例应用。 它演示了 XAML 布局、数据绑定和 UI 自定义功能。

注意

你可以看到在 UWP PhotoLab 示例应用的 Windows 应用 SDK 迁移中完全手动迁移的 PhotoLab 示例的案例研究。

  1. 先从上面的链接克隆或下载 PhotoLab 示例源代码。

提示

请注意,使用该工具自动迁移应用后,需要额外的手动操作才能完成迁移。

  1. 在 Visual Studio 中打开 PhotoLab 解决方案。

  2. 安装 .NET 升级助手扩展(请参阅本主题前面的安装 .NET 升级助手)后,右键单击“解决方案资源管理器”中的项目,然后单击“升级”

  3. 选择“将项目升级到较新的 .NET 版本”选项

  4. 选择“项目就地升级”选项

  5. 选择目标框架。

  6. 单击“升级所选内容”

  7. .NET 升级助手运行,并在升级过程中在 Visual Studio 的“输出”窗口输出信息和状态

你可以关注进度栏,直到升级操作完成。

PhotoLab 示例应用的代码迁移包括

  • 对内容对话框和文件保存选取器 API 的更改。
  • 动画包的 XAML 更新。
  • 显示警告消息,并在 DetailPage.xamlDetailPage.xaml.csMainPage.xaml.cs 中为自定义后退按钮添加“任务列表”TODO
  • 实现后退按钮功能并添加“任务列表”TODO 以自定义 XAML 按钮
  • 系统会提供一个指向文档的链接,可用于了解有关后退按钮实现的详细信息。

生成的 .csproj 中的版本号将略有不同,但基本上如下所示(为简洁起见,删除了一些版本配置属性组):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <OutputType>WinExe</OutputType>
    <DefaultLanguage>en-US</DefaultLanguage>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
    <UseWinUI>true</UseWinUI>
    <ApplicationManifest>app.manifest</ApplicationManifest>
    <EnableMsixTooling>true</EnableMsixTooling>
    <Platforms>x86;x64;arm64</Platforms>
    <PublishProfile>win10-$(Platform).pubxml</PublishProfile>
  </PropertyGroup>
  <ItemGroup>
    <AppxManifest Include="Package.appxmanifest">
      <SubType>Designer</SubType>
    </AppxManifest>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.1.0" />
    <PackageReference Include="Microsoft.Graphics.Win2D" Version="1.0.0.30" />
    <PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers" Version="0.4.346201">
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
    <PackageReference Include="CommunityToolkit.WinUI.UI.Animations" Version="7.1.2" />
  </ItemGroup>
  <ItemGroup>
    <Compile Remove="App.xaml.old.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.xaml.old.cs" />
  </ItemGroup>
</Project>

如你所见,项目现在引用了 Windows 应用 SDK、WinUI 3 和 .NET 6。 现在,PhotoLab 迁移完毕,你可以利用 WinUI 3 应用提供的所有新功能,并通过平台扩展应用

此外,.NET 升级助手还会向项目添加分析器,以帮助继续执行升级过程。 例如,Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers NuGet 包

后续手动迁移

此时,可以打开已迁移的 PhotoLab 解决方案或项目,并查看源代码中所做的更改。 项目需要一些工作来完成连接,之后才会构建和运行 WinUI3 版本,且该版本表现得像 UWP 版本一样。

请参阅 Visual Studio 中的“任务列表”(“查看”>“任务列表”),了解为了手动完成迁移而务必要做的待办事项 (TODO)

你的应用的 UWP (.NET Framework) 版本可能包含项目实际未使用的库引用。 你需要分析每个引用并确定它是否是必需的。 该工具可能还添加或升级了对错误版本的 NuGet 包引用。

升级助手不会编辑 Package.appxmanifest,而应用启动需要一些编辑:

  1. 在根 <Package> 元素上添加此命名空间:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  1. 将 <Application> 元素从 EntryPoint="appnamehere.App" 编辑为 EntryPoint="$targetentrypoint$"

  2. 将任何指定的 Capability 替换为以下项:

<rescap:Capability Name="runFullTrust" />

.csproj 文件中,可能需要编辑项目文件才能设置 <OutputType>WinExe</OutputType><UseMaui>False</UseMaui>

若要使用许多 XAML 控件,请确保 app.xaml 文件包含 <XamlControlsResources>,例如在以下示例中:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
            <!-- Other merged dictionaries here -->
        </ResourceDictionary.MergedDictionaries>
        <!-- Other app resources here -->
    </ResourceDictionary>
</Application.Resources>

故障排除提示

使用 .NET 升级助手时,可能会出现一些已知问题。 某些情况下,.NET 升级助手在内部使用的 try-convert 工具会出现这些问题。

但是,若要了解更多故障排除提示和已知问题,请参阅升级助手 GitHub 存储库。