Edit

Legacy .NET Upgrade Assistant guidance for UWP

Important

.NET Upgrade Assistant is deprecated. Don't use it to start a new migration. This article remains available for teams that need to maintain or reproduce an existing C# UWP-to-WinUI 3 migration that used the tool.

GitHub Copilot upgrade replaces .NET Upgrade Assistant for supported .NET upgrades, but it doesn't currently document UWP-to-WinUI 3 as a supported upgrade path. For a new UWP migration, follow Migrate from UWP to the Windows App SDK or use the AI-assisted UWP migration guidance.

The remaining sections describe the legacy tool's behavior and limitations.

Install the legacy tool

If you need to reproduce or continue an existing migration, you can enable the built-in legacy .NET Upgrade Assistant in a supported version of Visual Studio or install it as a .NET command-line tool. For more info, see Install the .NET Upgrade Assistant.

Summary

When you use the .NET Upgrade Assistant to migrate your UWP app, here are the high-level steps and stages in the migration process that the tool carries out.

  • Optionally copies your project, and migrates the copy; leaving your original project unchanged.
  • Optionally migrates your project in-place (in the same folders and files, without renaming folders); and doesn't make a copy.
  • Upgrades your project from the .NET Framework project format to the latest .NET SDK project format.
  • Cleans up NuGet package references. In addition to the packages referenced by your app, the packages.config file contains references to the dependencies of those packages. For example, if you added reference to package A, which depends on package B, then both packages would be referenced in the packages.config file. In the new project system, only the reference to package A is required. So this step analyzes the package references, and removes those that aren't required. Your app is still referencing .NET Framework assemblies. Some of those assemblies might be available as NuGet packages. So this step analyzes those assemblies, and references the appropriate NuGet package.
  • Targets .NET 6, and the Windows App SDK.
  • Changes the target framework moniker (TFM) (see Target frameworks in SDK-style projects) from .NET Framework to the suggested SDK. For example, net6.0-windows.
  • Migrates your UWP source code from WinUI for UWP to WinUI, performing source-specific code changes.
  • Adds/updates any template, config, and code files. For example, adding necessary publishing profiles, App.xaml.cs, MainWindow.xaml.cs, MainWindow.xaml, and others.
  • Update namespaces, and adds MainPage navigation.
  • Attempts to detect and fix APIs that are different between UWP and the Windows App SDK, and uses Task List TODOs to mark APIs that are no longer supported.

As it runs, the tool also aims to provide migration guidance in the form of warning messages within the tool's output, and Task List TODOs in the form of comments within your project's source code (for example, for cases where completely automated migration of your UWP source code isn't possible). A typical Task List TODO includes a link to a topic in this migration documentation. As the developer, you're always in control of the migration process.

Tip

To see all of the TODOs that the tool has generated, look in the Task list in Visual Studio.

Note

After the tool has finished running, there are some follow-up steps you can choose to do if needed. You can move your code from App.xaml.old.cs to App.xaml.cs; and you can restore AssemblyInfo.cs from the backup that the tool creates.

What the tool supports

The deprecated tool's UWP migration support applies only to C#, not C++. In most cases, your project requires additional manual work to complete the migration.

The tool aims to migrate your project and code so that it compiles. But some features require you to investigate and fix them (via Task List TODOs). For more information about what to consider before migrating, see What's supported when migrating from UWP to WinUI.

The legacy UWP migration workflow has the following limitations:

Where possible, the tool tries to generate a warning; and it intentionally causes your code not to compile until you change it.

  • Custom views aren't supported. For example, you won't receive a warning or a fix for a custom dialog that extends MessageDialog, and calls an API incorrectly.
  • Windows Runtime Components aren't supported.
  • Multi-window apps might not be migrated correctly.
  • A project that follows a non-standard file structure (such as App.xaml and App.xaml.cs not being in the root folder) might not be migrated correctly.

Note

For guidance about the migration process—and the differences between UWP and Windows App SDK features and APIs—see Migrate from UWP to the Windows App SDK.

Tip

You can see what version of the tool you have by issuing the command upgrade-assistant --version.

Test drive the tool with the UWP PhotoLab sample

Let's take the .NET Upgrade Assistant for a test-drive.

As source material, we'll be migrating the UWP PhotoLab sample application. PhotoLab is a sample app for viewing and editing image files. It demonstrates XAML layout, data binding, and UI customization features.

Note

You can see a case study of the PhotoLab sample being fully manually migrated in A Windows App SDK migration of the UWP PhotoLab sample app.

  1. Begin by cloning or downloading the PhotoLab sample source code from the link above.

Tip

Be aware that after we've used the tool to automate the migration of the app, additional manual effort will be needed to complete the migration.

  1. Open the PhotoLab solution in Visual Studio.

  2. Having installed the .NET Upgrade Assistant extension (see Install the legacy tool earlier in this topic), right-click on the project in Solution Explorer, and click Upgrade.

  3. Choose the Upgrade project to a newer .NET version option.

  4. Choose the In-place project upgrade option.

  5. Choose a target framework.

  6. Click Upgrade selection.

  7. The .NET Upgrade Assistant runs, and uses the Visual Studio Output window to print out info and status as it goes.

You can monitor the progress bar until the upgrade operation completes.

Code migration for the PhotoLab sample app includes:

  • Changes to Content Dialog and File Save picker APIs.
  • XAML update for the Animations package.
  • Showing warning messages, and adding Task List TODOs in DetailPage.xaml, DetailPage.xaml.cs, and MainPage.xaml.cs for custom back button.
  • Implementing the back button functionality and adding a Task List TODO to customize XAML button.
  • A link to documentation is provided that you can use to learn more about back button implementation.

The version numbers in your resulting .csproj will be slightly different, but essentially it will look like this (with some of the build configuration property groups removed for brevity):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.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>win-x86;win-x64;win-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>

As you can see, the project is now referencing the Windows App SDK, WinUI, and .NET 6. Now that PhotoLab has been migrated, you can take advantage of all of the new features that WinUI apps have to offer, and grow your app with the platform.

Also, the .NET Upgrade Assistant adds analyzers to the project that assist with continuing with the upgrade process. For example, the Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers NuGet package.

Follow-up manual migration

At this point you can open the migrated PhotoLab solution or project, and see the changes that have been made in the source code. The project needs a little more work to finish hooking things up before the WinUI version builds, runs, and behaves like the UWP version.

See the Task List in Visual Studio (View > Task List) for TODOs that you should action to manually complete the migration.

It's possible that the UWP (.NET Framework) version of your app contained library references that your project isn't actually using. You'll need to analyze each reference, and determine whether or not it's required. The tool might also have added or upgraded a NuGet package reference to the wrong version.

The Upgrade Assistant doesn't edit the Package.appxmanifest, which will need some edits in order for the app to launch:

  1. Add this namespace on the root <Package> element:
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  1. Edit the <Application> element from EntryPoint="appnamehere.App" to EntryPoint="$targetentrypoint$"

  2. Replace any specified Capability with this:

<rescap:Capability Name="runFullTrust" />

In your .csproj file, you might need to edit the project file to set <OutputType>WinExe</OutputType> and <UseMaui>False</UseMaui>.

To use many of the XAML controls, ensure that your app.xaml file includes the <XamlControlsResources>, such as in this example:

<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>

Troubleshooting tips

There are several known problems that can occur when using the .NET Upgrade Assistant. In some cases, these problems are with the try-convert tool that the .NET Upgrade Assistant uses internally.

For current guidance about completing the migration manually, see Migrate from UWP to the Windows App SDK.

See Also