WP8.1 - Creating/Deploying Appx Packages Using Command-Line
To those who are used to grabbing their packaged .XAP file from the Debug/Release directory, things have change with Windows Phone 8.1 (non-silverlight) apps. Instead, we are presented with two ways to create appx packages:
- Navigating to Project->Store->Create Store Package within Visual Studio 2013 (if you're looking for a store-ready appx, then this is your option to take)
- Using the Command Line tools
This thread will focus on how to use the command line tools rather than use the Visual Studio.
First thing's first, we have two core applications that we're going to use in order to handle package management and deployment:
- makeappx.exe - C:\Program Files (x86)\Windows Kits\8.1\bin\x86
- AppDeployCmd.exe - C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.1\Tools\AppDeploy
This does as the filename suggests, make appx files.
The easiest way to build an appx file out of the contents of your Debug/Release directory is to run the following command:
makeappx pack /v /d c:\pathtodirectory /p c:\pathtoappx.appx /l
the /v argument enables verbose output, the /d argument is your directory, the /p argument is your output package and the /l argument disables validation checks on manifest data and resource files.
If you are indeed building the appx manually from your Debug/Resource directory, please make sure to include any .dlls and .winmds that you may be referencing in separate projects that aren't in the main output directory.
This is the command line version of the Windows Phone 8.1 Application Deployment program.
The easiest way to deploy an appx to your phone is to run the following command:
AppDeployCmd /install c:\pathtoappx.appx /targetdevice:de /leaveoptimized
The /install argument provides the path to the appx file you wish to deploy, the /targetdevice argument is the device that you wish to deploy to and the /leaveoptimized argument is an optional parameter to leave the optimized version of the appx package on the filesystem instead of deleting it.
Analyzing the contents of an appx package:
The Appx file is different from a Xap file in that it is ZIP64 compressed instead of using the common ZIP compression. As of now, it isn't possible to deploy a ZIP compressed appx or modify a ZIP64 compressed appx file.
Taking a look a generated appx package, you'll see contents similar to the following:
- Assets - Assets directory
- App.exe - Main exe
- resources.pri - compiled resources
- App.xbf - Binary XAML file for the App namespace (similar to App.xaml for Silverlight)
- MainPage.xbf - Binary XAML file fro the Main Page (similar to MainPage.xaml for Silverlight)
- [Content_Types].xml - XML file containing the content type of every file in the package
- App.xr.xml - XML file containing the root XAML types of the app
- AppxBlockMap.xml - XML file containing a crypto hash for each block of data stored in the package
- AppxManifest.xml - XML file containing the main manifest (similar to WMAppManifest.xml in Silverlight)
When you deploy the appx to your device while using the /leaveoptimized flag, you'll notice a new appx file in the format of nameofappx_Optimized.appx.
This specific appx package is generated every time you sideload an app to your phone and is the version that your phone receives. The deployer runs MDILXapCompile on every file in the package to precompile any managed assemblies into native code.
If you open up the optimized appx file, you'll notice that we have two new files:
Things to be wary of with Windows Phone 8.1 appx packages and the Store:
- MDILXapCompileLog.txt - The output log of MDILXapCompile
- MDILFileList.xml - XML file that contains the assemblies that were successfully converted to native code.
I've posted this on twitter earlier this week, but for pure Windows Phone 8.1 applications, it is possible to retrieve their contents from the Store by using the Download and install manually link. The appx files on the Store ARE NOT ENCRYPTED
. From my understanding, it has to do with keeping compatibility between Windows 8.1 and Windows Phone 8.1. I'm curious to know when they decide to encrypt the files.
What's this have to do with the topic at hand? Everything. It is also possible to repackage an appx file from the Store
Before I get into the how-to and the caveats, I'll explain how I even discovered the appx files were unencrypted.
I happened to be researching a particular capability I've been seeing in some files in a ROM dump from one of the newer Lumias and happened to paste it in to Bing. I was shocked to see direct links to the appx packages and noticed some familiar file names in the description of the link (AppxManifest.xml and MDILFileList.xml were the two that caught my eye). The even bigger kicker was the fact that these appx files are indeed searchable, but only from Bing (and DuckDuckGo which happens to use Bing). I decided to make more specific search queries to see if this was legit or if I happened to be losing my mind. It turns out that I wasn't.
"site:windowsphone.com/en-us AppxManifest.xml" happens to be the holy grail and will return any indexed Windows Phone 8.1 apps. The scary part is that you can still download apps that aren't published anymore and side load them. Here's an example Windows Phone 8.1 app that I happened to download (and also happens to be a Microsoft app).
The link is self-explanatory. It's the Microsoft Remote Desktop Preview app. Now for the fun part.
Repackaging an app for development and testing purpose:
Before I begin this, I'm going to put a disclaimer out there, that this is just information to be used for dev purposes and as a way of trying to understand more of the packing process. I am by no means condoning any piracy
so do NOT ask any questions or make any statements that involve searching for apps that you can't find, etc. I'm hoping Microsoft fixes this hole soon.
In the contents of the downloaded appx file, you'll notice we have even more files:
- AppxSignature.p7x - Signature for app.
- AppxMetadata - folder containing the CodeIntegrity security catalog file
To repackage and deploy an app to your device, the following must be done:
Common issues with redeployment:
- Extract the contents of the appx into a blank folder
- Remove MDILFileList.xml, AppxSignature.p7x, and the AppManifest folder
- Run the makeappx command above to repackage
- Run the AppDeployCmd command above to deploy the app to your device
"Oh crap! I'm worried about people stealing my code, what do I do?
- If it's an update to a System app (Calendar, Podcast), you won't be able to install it because it can't uninstall the app from your phone
- If it is a Microsoft or OEM app, you're most likely going to be unable to deploy it due to restricted capabilities. Some appx packages will include a WindowsPhoneReservedAppInfo.xml file that will contain the extra capabilities. You're free to remove them, but don't count on it actually working
- If the appx package contains an external DLL reference that isn't from your project (Live SDK dll for instance), you will receive an error deploying with a message stating that the assembly can't be optimized because it is an invalid assembly.
I've tried two workarounds in order to actually allow the deployment:
- Remove the strong name key
- and replace the dll with a version downloaded from the repository.
I tried this on an app, but the app will still crash when it tries to call functions that use the external dll
- Use Silverlight if you're doing a Windows Phone 8.1 app. Those are still encrypted from the store (Until someone installs the app with an interop-unlocked phone)
- Use WinRT C++ instead of C#. Yeah, that's the most difficult and crappy way to go, but it will make it a little harder (not impossible) for someone to jack your code
Again, I'm hoping that MS addresses this, but for now it is a nice way to analyze changes done in apps like the Calendar and Files app.
Happy testing folks