Upgrading to Windows Phone 8.1: How to support Silverlight 8.0 and 8.1 in the same project

While working on my most recent update to Car Dash I upgraded the app to target 8.1. The process was easy, but I didn’t want to have to fork my codebase in order to continue supporting 8.0 devices. I’d much rather have one project that could build for 8.0 and 8.1 with a configuration switch. Today I’ll share the process I went through, highlight the differences I found between the two versions and share a sample project.

Before we upgrade our project we’re going to create 2 new solution configurations. We’ll name them “WP8.1 Debug” and “WP 8.1 Release” with settings copied from Debug and Release respectively.

When you upgrade your project from WP8 to WP8.1 Visual Studio will prompt you to create a backup first. You should definitely do this, especially if you are not using a source control like git or subversion. For this exercise though I’m creating a copy of the .csproj just so that I can compare it against the retargeted version.

A few things happen when you retarget the project. A few new png files are added to your Assets folder: BadgeLogo, Logo, SplashScreen, SquareTile150x150, SquareTile71x71, StoreLogo and WideLogo. All of these assets will have a square with an X in it, and will need to be replaced with the actual branded assets for your app before you release. The Package.appxmanifest file is also added, you can find more information about the upgrade process here on msdn.

We want to look at what changes are made to the project file itself though, so lets unload the project from Visual Studio and take a look. I used KDiff3 to compare the backed up csproj file against the WP8.1 csproj file:

We’ll start by looking at the changes in the Global PropertyGroup. You can see that the TargetFrameworkVersion predictably changed from v8.0 to v8.1, also the SilverlightVersion changed from TargetFrameworkVersion (v8.0) to a null value. Not really sure why SilverlightVersion would be nulled out now, but we can use Conditional’s to resolve these differences in our new project. There are also two new nodes: TargetFrameworkProfile (with an empty tag, weird) and DefaultLanguage.

<TargetFrameworkVersion Condition="!$(Configuration.Contains('WP8.1'))">v8.0 </TargetFrameworkVersion> <TargetFrameworkVersion Condition="$(Configuration.Contains('WP8.1'))">v8.1 </TargetFrameworkVersion> <SilverlightVersion Condition="!$(Configuration.Contains('WP8.1'))">$(TargetFrameworkVersion) </SilverlightVersion> <SilverlightVersion Condition="$(Configuration.Contains('WP8.1'))"> </SilverlightVersion> 1 2 3 4 5 6 7 8 9 10 11 12 & lt ; TargetFrameworkVersion Condition = "!$(Configuration.Contains('WP8.1'))" > v8 . 0 & lt ; / TargetFrameworkVersion > & lt ; TargetFrameworkVersion Condition = "$(Configuration.Contains('WP8.1'))" > v8 . 1 & lt ; / TargetFrameworkVersion > & lt ; SilverlightVersion Condition = "!$(Configuration.Contains('WP8.1'))" > $ ( TargetFrameworkVersion ) & lt ; / SilverlightVersion > & lt ; SilverlightVersion Condition = "$(Configuration.Contains('WP8.1'))" > & lt ; / SilverlightVersion >

Now we’ll look at the differences made to the different Configuration PropertyGroups, there really isn’t much changed here though. A PlatformTarget node is added, but it has no value. I decided to remove <PlatformTarget/> from my Debug/Release configurations that will be used for Windows Phone 8.0 builds though, just to be safe.

So at this point we have our WP 8.1 Configuration’s and we’ve made changes in the Global PropertyGroup to use the correct version based on the current Configuration selection. We also need to add Conditional statements to the Package.appxmanifest and the various new Assets files that were added since we only need those for Windows Phone 8.1:

<AppxManifest Include="Package.appxmanifest" Condition="$(Configuration.Contains('WP8.1'))"> <SubType>Designer</SubType> </AppxManifest> 1 2 3 4 & lt ; AppxManifest Include = "Package.appxmanifest" Condition = "$(Configuration.Contains('WP8.1'))" > & lt ; SubType > Designer < / SubType > & lt ; / AppxManifest >

The last difference to be addressed are with the WMAppManifest.xml files. When comparing the old and new WMAppManifest we can see that there is an updated xml namespace, and the AppPlatformVersion changes from 8.0 to 8.1. To address this difference between the two platforms we’ll have to save 2 different versions of the WMAppManifest file and switch to the appropriate one with a pre-build step:

Now we can reload our project and see if we can switch from WP 8.0 to 8.1 and back.

It worked! Although there is one caveat. When you switch from your WP8.0 configuration to WP8.1 and vice versa your project will not update it’s label (where it says Windows Phone Silverlight 8.0 or 8.1). If you unload the project and reload though the label does get updated properly. You don’t need to do the unload/reload for the build process to work though.

I currently have builds generated from this method uploaded for the Beta version of Car Dash and it seems to be working well. I am not using any new 8.1 APIs yet, but if you want to add some 8.1 specific code to your project you can create a new Conditional Compilation Symbol for your 8.1 projects, and use #ifdef’s to wrap your 8.1 code.

If you want to look at the demo solution I built while testing this you can find it on my github here: https://github.com/robwirving/PhoneApp_SL_8.05