Windows 8.1–Resource Packages and App Bundles

One of the things that I’d heard about in a couple of places for a Windows 8.1 store app was the idea that work had been done to improve the situation where you might have an app that supported a number of different variants such as;

  • processor architecture (x86, x64, ARM)
  • language (e.g. English, French)
  • display scaling (e.g. 80, 100, 140, 180)
  • and even more (to me) esoteric options like DirectX feature level support

Generally, these things don’t change on a user’s system and so it would make sense to split up an application’s code & resources such that at deployment time the system could be smart enough to only download the bits that were needed for that particular machine.

On Windows 8.0 this didn’t happen and different architectures had to be submitted into the Store separately but Windows 8.1 improves this with “App Bundles” and “Resource Packs”.

This is pretty well explained up on MSDN and I found it was really worth reading down to the bottom of that document to try and get a handle on what’s going on. In short, my simplistic understanding is;

  • App Packages are very much still the unit of currency but there’s a new type of app package which is one that only contains resources for a particular combination of language/scale/etc.
  • App Packages can now be bundled into an app bundle so that a number of (e.g.) architectures (x86/x64/ARM) can all be put into one bundle along with a number of resource packs and the whole thing can be submitted to the Store in one go
  • The system is smart at deployment time (or at points in time when criteria might change) to only download and install what’s needed for a particular user on a particular machine

There’s a great video up on Channel 9 which explains this better than I just did;

and another good way of illustrating it is to take the “Application Resources” sample from the developer centre and then drop it into Visual Studio 2013 and create an application package from it. That is – if you have a look around that project you’ll notice both English, French and Japanese resources and also resources (images in this case) at different scales;

image

and then on the dialog ensure that you’re asking Visual Studio to magically create an app bundle for you;

image

Then have a look in the resulting .appxbundle file (by renaming it to a .zip file);

image

image

and you can see the separated out 140, 180, French and Japanese resources. Note that (as far as I know) not all resources will be separated out because the resources for the default language have to be present.

You can also have a poke around in the AppMetadata folder and see the XML description of the bundle breaking down the different packages in my case as below;

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Bundle xmlns="http://schemas.microsoft.com/appx/2013/bundle" SchemaVersion="1.0">
	<Identity Name="Microsoft.SDKSamples.ApplicationResources.CS" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="2013.919.1827.1392"/>
	<Packages>
		<Package Type="application" Version="1.0.0.0" Architecture="neutral" FileName="ApplicationResources_1.0.0.0_AnyCPU_Debug.appx" Offset="76" Size="161818">
			<Resources>
				<Resource Language="EN"/>
			</Resources>
		</Package>
		<Package Type="resource" Version="1.0.0.0" ResourceId="split.language-fr" FileName="ApplicationResources_1.0.0.0_language-fr.appx" Offset="161993" Size="4488">
			<Resources>
				<Resource Language="fr-fr"/>
			</Resources>
		</Package>
		<Package Type="resource" Version="1.0.0.0" ResourceId="split.language-ja" FileName="ApplicationResources_1.0.0.0_language-ja.appx" Offset="166580" Size="33307">
			<Resources>
				<Resource Language="ja"/>
			</Resources>
		</Package>
		<Package Type="resource" Version="1.0.0.0" ResourceId="split.scale-140" FileName="ApplicationResources_1.0.0.0_scale-140.appx" Offset="199984" Size="22592">
			<Resources>
				<Resource Scale="140"/>
			</Resources>
		</Package>
		<Package Type="resource" Version="1.0.0.0" ResourceId="split.scale-180" FileName="ApplicationResources_1.0.0.0_scale-180.appx" Offset="222673" Size="27150">
			<Resources>
				<Resource Scale="180"/>
			</Resources>
		</Package>
	</Packages>
</Bundle>