Upgrade a .Net Framework WPF Application to .Net Core 3.x
Tags: dotnet, desktop, wpf
Published: 2019-11-25 13:16:44

One of the main things that was introduced as part of .Net Core 3 was the ability to upgrade your WinForms or WPF application to use Core. I have an example of such an application <a href="https://github.com/pcmichaels/WindowsDesktopTalk/tree/master/Wpf-Legacy-1/Wpf-Upgrade-Kiosk">here</a>. This was upgraded using the side-by-side method. If you are upgrading, you essentially have 2 options: Big Bang and Side-by-Side.
<h2>Big Bang Upgrade</h2>
This is the process by which you edit your csproj file on the framework app, and convert that file to use .Net Core 3. This means potentially less work, and is suited for a situation where you know that you will never need the original application again. For a personal project this may be fine, but realistically, it too big a risk for most companies, who would want the security of a gradual rollout, and the ability to fix bugs and make interim releases in the meantime.
<h2>Side-by-Side Upgrade</h2>
There are three ways to do this, but essentially, what you're doing here is creating a second project that is running .Net Core. The benefit here is that the two applications can continue to run, and you can gradually discontinue the Framework app as and when you see fit. The work involved can be greater; but it varies depending on your methodology and requirements.
<h3>1. Copy and Paste</h3>
This is the simplest method: create a brand new .Net Core WPF application, and copy the entire contents of your directory across. You'll need to convert the packages (covered later), but other than that, you should be good to go. Obviously, that depends hugely on the complexity of your project.

The downside here is that if you fix a bug, or make a change to one of these projects, you either need to do it twice, or have them get out of sync.
<h3>2. Two Projects One Directory</h3>
This seems to be <a href="https://www.youtube.com/watch?v=OYAkmB8cQrs">Microsoft's preferred approach</a>: the idea being that you create a new .Net Core project <em>inside the same directory</em> as the .Net Framework app. This means that all the files just appear in your framework app. You'll need to convert the packages, and exclude the csproj, and other .Net Framework specific files from the .Net Core project. This, and the following approach both give you the ability to change the code in both files simultaneously.
<h3>3. Two Projects Linked Files</h3>
This is my personal preference. You create your .Net Core project it a different directory and just link the files and directories. You get all the benefits of having the projects in the same directory, but without the hassle of trying to manage files being there that you don't want.

The downside to this approach is that you need to include the files yourself.
<h1>Two Projects Linked Files Upgrade</h1>
The following steps, whilst for this particular approach, are not specific to it, unless stated.

1 - Start by installing the UWP Workload in Visual Studio, assuming you haven't already.

2 - In your WPF Framework app, convert your packages.config, as that doesn't exist in .Net Core:

<a href="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-1.png"><img class="alignnone size-full wp-image-3990" src="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-1.png" alt="" width="850" height="675" /></a>

3 - Create a new project. Whilst this is specific to this approach, you will need a new project for any of the side-by-side methods.

For this method, the project needs to be in a different directory; my suggestion is that you put it inside the solution directory, under its own folder; for example, in the example above, you might create: WpfCoreApp1:

<a href="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-2.png"><img class="alignnone size-full wp-image-3989" src="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-2.png" alt="" width="434" height="610" /></a>

The directory structure might look like this:

<a href="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-3.png"><img class="alignnone size-full wp-image-3988" src="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-3.png" alt="" width="853" height="243" /></a>

4 - Copy the package references from your packages.config directly into the new csproj file (following step 1, this should be a simple copy and paste).

5 - Gut the new project by removing MainWindow.xaml and App.xaml (from here on in, all of the steps are specific to this method):

<a href="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-4.png"><img class="alignnone size-full wp-image-3987" src="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-4.png" alt="" width="527" height="533" /></a>

6 - Edit the new csproj file. Depending on your directory structure, the following may differ, but broadly speaking you need the following code in your new csproj file:

```xml
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>
  <ItemGroup>
    <ApplicationDefinition Include="..\WpfApp1\App.xaml" Link="App.xaml">
      <Generator>MSBuild:Compile</Generator>
    </ApplicationDefinition>
    <Compile Include="..\WpfApp1\App.Xaml.cs" Link="App.Xaml.cs" />
    <Page Include="..\WpfApp1\MainWindow.xaml" Link="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Compile Include="..\WpfApp1\MainWindow.Xaml.cs" Link="MainWindow.Xaml.cs" />
  </ItemGroup>
</Project>
```

If, for example, you were to have a directory that you wished to bring across, you could use something similar to the following:

```xml
  <ItemGroup>
    <Compile Include="..\WpfApp1\Helpers\**">
      <Link>Helpers\%(Filename)%(Extension)</Link>
    </Compile>
</ItemGroup>
```

That's it - you should now be able to set your new .Net Core project as start-up and run it. The code is the same code as that running the Framework app, and should you change either, it will affect the other.

As an addendum, here is a little chart that I think should help you decide which approach to take for an upgrade:

<a href="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-5-scaled.png"><img src="https://www.pmichaels.net/wp-content/uploads/2019/11/wpf-5-scaled.png" alt="" width="2560" height="1135" class="alignnone size-full wp-image-4003" /></a>