If you have spent any time at all working on Windows Store apps, then you have become familiar with the package.appxmanifest file. This is a very important part of your application and helps define how your application will run within Windows 8. At a very basic level, this is where you set things like the name, description, and the default logos for your application. However, the meat of the AppxManifest is the capabilities and declarations sections. These sections are where you inform Windows 8 what level of access your application requires to run on a user’s machine. This provides security and transparency to the user. For instance, the user might want to know what a weather application needs access to the computer’s webcam.
On the other hand, it is also important to identify any capabilities that your application does need access to. If your application attempts to open a file on the user’s Document library and the “Document Library” capability is not set, then a runtime error will be generated.
Since the AppxManifest can therefore have an operational effect on your application, it might come in handy to know what your application can and can’t do. In addition, you might want to know things like what image is being used as the splash screen logo or what the background color is set to. This type of access can become particularly valuable when you are constructing reusable class libraries that might behave differently depending on the current application’s capabilities.
Before we look at doing things the hard way, it is important to note that there are a couple of classes within the WinRT API that will expose some of the information within the AppxManifest: Package and PackageId. The application’s Package class can be accessed through the static property Windows.ApplicationModel.Package.Current. The Package class provides some basic information about the application, specifically some installation information and dependencies. The PackageId provides information about the application’s name, version, and publisher’s information. The current application’s PackageId can be found in the Id property of the current Package class. These two classes are the first place you should start. You can find more specifics about these two classes on MSDN at http://tonyc.me/WOIDiC. The following snippet shows how to get the current application’s installation location, publisher name, and version.
var package = Windows.ApplicationModel.Package.Current; var packageId = package.Id; // Returns StoreFolder of installation var installLoc = package.InstalledLocation; // Returns Publisher's name var publisher = packageId.Publisher; // Returns apps name var name = packageId.FullName;
If the Package and PackageId classes don’t have the information that you are looking for then maybe it’s time to continue on and look at the AppxManifest directly. However, first let’s take a closer look at the package.appxmanifest that is a part of each Windows Store app.
<?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest"> <Identity Name="46b29794-8225-420d-84cb-f807e550de29" Publisher="CN=Tony" Version="188.8.131.52" /> <Properties> <DisplayName>App9</DisplayName> <PublisherDisplayName>Tony</PublisherDisplayName> <Logo>Assets\StoreLogo.png</Logo> </Properties> <Prerequisites> <OSMinVersion>6.2.1</OSMinVersion> <OSMaxVersionTested>6.2.1</OSMaxVersionTested> </Prerequisites> <Resources> <Resource Language="x-generate"/> </Resources> <Applications> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="App9.App"> <VisualElements DisplayName="App9" Logo="Assets\Logo.png" SmallLogo="Assets\SmallLogo.png" Description="App9" ForegroundText="light" BackgroundColor="#464646"> <DefaultTile ShowName="allLogos" /> <SplashScreen Image="Assets\SplashScreen.png" /> </VisualElements> </Application> </Applications> <Capabilities> <Capability Name="internetClient" /> </Capabilities> </Package>
Let’s flash forward in the development cycle to where you have completed your code, set your application properties and capabilities in the package.appxmanifest, and have built your application to deploy. What happens to the package.appxmanifest during the build process? Does it generate some secret code somewhere never to be seen again? Nope. It actually is used to generate a file, AppxManifest.xml, that is included in the final package. If you build your application and then look in the bin\debug folder of your solution, you will find the generated AppxManifest.xml file. If you open the file you will notice that it looks strikingly similar to the XML in the package.appxmanifest we just looked at. In fact the only difference is some build metadata that has been added. This AppxManifest.xml file is included in every Windows Store app and is the key to determining your applications settings at runtime.
There is one additional point that I’d like to point out about the package.appxmanifest. As you have seen, it is used to generate the AppxManifest.xml file for the package, however, it is not required to be a part of your solution. You can always remove it from the solution and manually add the AppxManifest.xml directly or it could be a part of your build process. This could come in handy if you want to require certain application restraints during the build cycle.
Reading the AppxManifest.xml as Runtime
At this point, you have likely guessed where we are going with this post. If each package contains an AppxManifest.xml file then it should be easy enough to read it at runtime. In fact, it actually is that easy. The following code will load the AppxManifest.xml into a XDocument that we can then use to read. The following example demonstrates how to get the local path to the splash screen for the application.
var doc = XDocument.Load("AppxManifest.xml", LoadOptions.None); // Define the default namespace to be used var xname = XNamespace.Get("http://schemas.microsoft.com/appx/2010/manifest"); // Get the SplashScreen node located at Package/Applications/Application/VisualElements/SplashScreen var splashScreenElement = doc.Descendants(xname + "SplashScreen").First(); // The Image attribute holds the local path to the Splash Screen image for the application var splashScreenPath = splashScreenElement.Attribute("Image").Value;
Using this approach, you are able to pull any of the information within the application’s AppxManifest at runtime. The only thing remaining is to gain an understanding of the schema. Fortunately, Microsoft has posted the schema on MSDN and you can find that at http://tonyc.me/11hgQbm.