I wrote my first Windows 8 Metro application right before Øredev 2011. It was a small application that basically just displayed all tracks and speakers at the conference. I had the luxury of having access the raw conference xml data from the server, but one thing that I have learnt from conferences is that the Wi-Fi, always, without exceptions – suck. So my plan was to download the xml files, deploy them with the application and then read them from disk… this is my story.
The working title was actually “Allowing Windows 8 Metro applications to access files”, but I think that this one has more Omph! to it.
Someone moved my cheese!
If this was a normal application and I wanted to load a xml file from disk, I would probably do something like this.
XDocument xDocument = null;
using(var fileStream = File.OpenRead(@"C:data.xml"))
xDocument = XDocument.Load(fileStream);
But .NET Framework 4.5 and WinRT is something new and really different. Reading files from disk just are not what it used to be. Just start to write System.IO. and you get – well, not much.
With WinRT, any operation that potentially can run longer than 50 ms has been converted to an async method. So, when it comes to reading a file you get a bunch of them. After some frantic googling and experimentation (without ReSharper and with an American keyboard) I managed to create this async file reading method.
private async Task<XDocument> ReadFileAsync(string fileName)
var file = await KnownFolders.DocumentsLibrary.GetFileAsync(fileName);
var readable = await file.OpenAsync(FileAccessMode.Read);
uint size = (uint)readable.Size - 1;
var stream = readable.GetInputStreamAt(0);
var reader = new DataReader(stream);
var result = reader.ReadString(size);
Not quite as streamlined is it? I don’t know about you, but when I look at this, I certainly feel that I have a lot of new stuff to learn. So, did it work?
No. It did not.
May I please access a file?
To be a little more precise, nothing happened at all. Well, something did happen. An exception was thrown when I tried to read a file. But since Visual Studio 2011 is not by default set to always break for any thrown CLR exception I only got a line in my output window. With hindsight I probably should have looked there directly, but I didn’t. So I noticed this after quite some time.
WinRT information: Access to this location requires a corresponding capability.
A first chance exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
What it basically means is that you need to ask nicely before accessing any file. Also, you need to specify which kind of files you want to access and where you would like to access them. You can do this by opening your Package.appxmanifest found in your solution directory.
Since I had placed my xml files in “My Documents”, I first needed to add the capability to read from that folder. (click on the image to see a bigger version)
The next step was to declare my application association with xml files. In the tab Declarations you first chose to add File Type Associations.
Now you need to specify that it is a xml file that you want to read.
You can enter any name that you want and as file type I just entered “.xml”. Pressed F5 and launched my application. So did it work?
Yes. Yes it did.
To be perfectly honest
I’m not still not happy with my lack of understanding with how file access actually works. Right now it just seems overly complex to me. Important to note is that both Windows 8 Metro application development and WinRT is in an extremely early stage. A lot can still change.
Also – thanks to Håkan that helped me out with the application design.