I spent a bit of time today debugging a scenario which turned out to be really simple but had me foxed for a while and so I thought I’d share.
To simplify what I was looking at, let’s make a new, blank Windows 8.1 XAML project;
and, because I happen to have a little snippet available for it, let’s put a smiley face piece of XAML onto the MainPage.xaml just so that there’s something to see;
and, having not really done anything of any note that would all run fine in the way that I’d expect;
- If I hit F5 and debug it (the first time I do this would also involve deploying it).
- If I run it from the start screen without debugging it.
- If I build the application’s package via the Store menu in Visual Studio and then run the PowerShell script to install the app and then run the installed app from the Start Screen.
However, if I move that XAML file into a new location such as this one below;
Then what happens is;
- If I hit F5 and debug it then it works fine.
- If I run it from the start screen without debugging it, it all works fine.
However, if I build the application’s package via the Store menu in Visual Studio and then run the PowerShell script to install the app and then run the installed app from the Start Screen then what I see is the app’s splash screen followed by nothing. The app exits without any further notice and I don’t see the smiley face on the MainPage.xaml.
Now, in truth, that wouldn’t happen in the default case but it does happen if I’ve switched the packaging flag that says;
and, generally, I think that app bundles are a good thing so I’d usually have this flag set to “Always” or “As Needed”.
That switch probably highlights to you where I’m heading with this but I’ll walk through it in the way in which I ultimately “solved” the problem I had with someone’s much bigger, more complete app.
The problem with this scenario is how to debug it? The app only seems to exhibit the problem when it is run outside of the debugger which makes things a bit tricky.
The technique that I used was to install the app from its app package but then to use the “Debug Installed App Package…” option which I’ve mentioned previously;
as that has a really handy little option which launches the app under the debugger but I can ask it to stop at start-up;
and that breaks pretty quickly at;
and then I can toggle on the debugger’s exception support to see if there’s some first-chance exception information that might help me out;
and set the application running again until I hit;
and that points to this particular line of generated code which is responsible for loading up the XAML file;
and, trust me, in somebody else’s codebase it’s possible to then go and stare at the XAML file for quite a long time wondering what the heck could be wrong with it such that it parses under the debugger but doesn’t parse when run from the installed app package.
It can take a little time before you realise that this isn’t a problem in parsing the XAML file at all. It’s a problem in finding/reading the XAML file in the first place.
Why’s that? MRT. Modern Resource Technology. The bit of the Windows/Phone 8.1 platform which does the admirable job of allowing to have very flexible naming conventions for files/folders which lets you ship resources that vary by things such as locale, region, device display density, DirectX feature level, contrast scheme and many other things.
You can read up on MRT here if you’re not familiar with it: http://msdn.microsoft.com/en-us/library/windows/apps/jj552947.aspx
What’s that got to do with my XAML file here? The XAML file is basically going to end up as a resource and this generated attempt to load it;
is going to fail in my scenario. A dig into the .appxbundle built for the package reveals why. Having a look in there (after renaming it as a zip file);
gives a hint to the problem – what are these “uk” resources doing in there own .appx file? Renaming that .appx to a zip file and having a look in there shows what’s gone into that file;
The system has packaged the binary version of my MainPage.xaml (i.e. the .xbf file) into a “uk” specific package of resources, preserving the original folder structure from the Visual Studio project.
I’ll admit that before I saw this, I hadn’t realised that “uk” was a valid specifier here – I’ve always gone with en-GB myself but I am no doubt missing some subtlety and the system definitely seems to pick up “uk” but the codebase that I was looking at today had a “uk” in its folder hierarchy probably based on a x.y.z.co.uk type naming scheme.
Because my application’s manifest specifies a default language of;
it’s not going to pick up those “uk” resources and so, effectively, the XAML file for my MainPage doesn’t exist and the call to “parse” it fails. As an aside, a better exception here would have helped me a lot.
If I was to change the default language to “en-GB” and re-build the package and install it I would see the same problem – en-GB != uk.
However, changing the default language to “uk” resolves the problem as would changing the name of the folder to something other than “uk”.
That’s that – it took me longer to figure out than it took me to write the post but, hopefully, there’s a technique in there or two which might be useful to you in the future.
In short, take care how you name your files/folders in Windows/Phone apps – MRT is a great thing when you want it but you don’t want to make use of it accidentally.