Monday, April 8, 2019

Deploying a Xamarin UWP Project to a Surface Tablet


DotNet Core

I’ve been converting all my dev frameworks over from ASP NET Webforms to ASP .NET Core MVC over the last six months. Although the level of change has been epic, the result is decidedly worth it.  

The main issue I’ve encountered is that a number of third party products, for me reporting tools such as Telerik or DevExpress, still don’t support .NET Core, so we’re stuck in some cases with .NET Standard 2 (to maintain NET Core compatibility) and .NET 4.6. However the tipping point is quickly being reached, and .NET core ports are popping up all over the place.  Especially with Microsoft's announcement that they are stopping development on 'Classic' .NET, there is no doubt that .NET Core is the way of the future.

Xamarin and UWP

I have also been building my first mobile application with Xamarin. This has been a great experience in the main, because I can reuse so much of my existing infrastructure. It is a truly smooth toolset.

As always, however, the first time deployment to each platform (UWP, iOS or Android) has many pitfalls and can take days to sort out.  
The Microsoft documentation is, while improving from the abysmal quality of the old days, still pretty substandard. The constant churn of adding and dropping features means that most of what you can find is only partially, if at all, still true, and often quite cryptic into the bargain. They do well with reference material if you know what you’re looking for already, but in terms of laying out a clear overview of the elements of the situation, and clear steps to solve a problem, not so much. For that, we need StackOverflow.

Sideloading to UWP

So the following steps will no doubt change, probably rapidly, but this is a walkthrough of how to sideload a Xamarin UWP project as of April 2019. I will *not* be using the app store - this is a line of business (LOB) app which will be loaded directly onto the device.  
iOS and Android versions of this to follow soon.

1. Choose UWP version compatibility


This didn't cause me any problems, as I have a lot of control over my endpoint devices (which are also brand new), but when Googling for solutions to other problems, there were reports of weird errors due to Xamarin code from old SDK versions not being properly updated. This is a good factor to keep in mind when troubleshooting.

2. .NET Native

I read in several places that it was important to deploy code in release mode. This turns out not really to be true. Debug mode will perform perfectly well on the target device, and can be used for testing -
I think that the reason for the recommendation centres around .NET Native.



.NET Native is an additional step in the compile process that compiles to native Windows binaries, rather than the intermediate (IL) language that .NET normally uses. There are a few things to know about .NET Native:

  • the compilation process takes up to 20 times longer than a compilation without it
  • with it, you lose the ability to use the .NET reflection features (they are dependent on IL) and certain other features (see here for a very informative article)
  • by default, .NET produces packages *without* .NET Native in Debug mode, and *with* it in Release mode (this can be a bit unexpected)
  • it is claimed to speed up the application dramatically, but the article linked above does give mixed results in speed outcomes


Since I use an ORM (PetaPoco) that relies on reflection extensively, that immediately ruled out .NET Native for me.  I note that MS Entity Framework, and I think all ORMs realistically, use reflection.

The reason I had to investigate all this was that initially I just deployed with default settings in release mode (so, in hindsight, *with* .NET Native) and my application silently crashed on startup. No error message, no crash dump, nothing. I added exception handling right back to the first lines of startup with no change in behaviour. So it appears that if the application tries to use any of the forbidden features in .NET Native mode, it immediately crashes without any kind of notification or exception reporting. Great.

The 'Enable static anaysis' flag is meant to provide a screening mechanism to warn about code issues like the above. However, I couldn't get it to work out of the box, and because of the reflection issues, I didn't bother with it in the end.  I note that I also had some permissions issues with compilation initially ('Access to the path 'C:\Program Files (x86)\Windows Kits\10\App Certification Kit\SupportedAPIs-x64.xml' is denied.'), which required me to reset the permissions on that folder - likely just a hiccup with VS or the installer.

So in summary, you may wish to tackle .NET Native, but it does add a significant amount of complexity to the compilation process. My recommendation would be to leave it all swtiched off initially, until your application is tested and deployed, and then come back to it as an additional optimisation later on, allocating significant time for assessing feasibility and then testing it.

3. Ensure the target device (tablet) is not in S Mode

'S' mode locks the device to only using Windows Store apps to provide higher security. It can be switched out of S mode easily enough with no licensing implications, but note that once you've switched, you can't go back, even with an OS reinstall.

Check control panel -> System -> About, to see if your device is in S mode.

Here are the instructions to switch.

I note that the following steps were a lot easier if I switched explorer folder options to:  
- untick 'hide extensions for known file types'
- tick 'expand to current folder'

4. Install the project certificate

- double click the .cer file in the project deployment folder
- click 'install certificate'
- choose 'local machine'
- choose 'place all certificates ...', click 'browse'
- scroll down, select 'Trusted People' (I know that sounds crazy, but this is the one)
- finish

5. Install and Start the project

 Double click the '.appx' or '.appxbundle' file, click 'install' and then when installed, 'launch'

No comments:

Post a Comment