In my last post, I started a journey to see if I can share data between a WPF application and a Windows 8 Metro application. We left off with the data in the Metro application. According to the map the way back to the WPF application is through the Documents folder. Only when the data makes it back to the WPF application will our journey be complete. The WPF application can insert any data modified by the Metro application back into the database which is then synced back to the server. This demo shows a way to work with WPF and Metro applications in a disconnected environment. Enterprises may have legacy systems that work nicely disconnected. Now they can start migrating functionality to Metro applications and don’t have to abandon they stable desktop apps right away.
In the first post the WPF application saved off the data to a file in the bin directory using a file type that is only associated with the Metro applications. The WPF application then launched a process using that saved file. Since the Metro applications was the only application associated with that file type, the application launches and handles the contents of that file. You could do something similar to bring the data back to the WPF application but I wanted to try something different.
In the Metro world applications run in a strict sandbox and have no access to the world outside except in certain situations. With the user’s permission, Metro applications can access the library folders on the system. These folders include the Documents folder, the Music folder, and the Picture folder. So following our map above I will have the Metro application save the changes to a file in the Documents folder. Then I will have the WPF application pick up that file and process the changes.
The Metro App
Since we left off in the Metro application we will start there. Data has arrived from the WPF application and has been processed in the UI. Modifications have been made and now it is time to persist those changes back to the database.
In order to journey to the land of Documents the Metro application has to set the documents capability in the application manifest. This is a security precaution put in place by the Windows 8 operating system. The user is in control and can revoke this permission at any time so keep that in mind when architecting your applications to uses any library folders.
As another security precaution Metro application can only write out files for which it has a file type association. If you do try to write out to the folder without the type association you will get a security exception stating you don’t have permission to that folder. This prevents your from access files that the user has not given you permission to access. In the first part of this series I created an association to a type that is user to launch the app. I did not want to reuse that type association so I added a second on to the declarations in the application manifest.
Now the only thing left to do is save the data to the documents folder. Here is the code that handles that task:
I start by creating a file name and in order to ensure I don’t overwrite a file that has not been processed I use the ticks from the DateTime object to ensure uniqueness (Line 73). Note the use of the new file type. Next I grab a reference to the DocumentsLibrary which is available through the KnownFolders object (Line 74). I then get a reference to the a subfolder (Line 75) where I create the file I am going to use (Line 76). In Line 79-83 I stream the serialized object out to the newly created file.
Keep in mind I am able to share data because the person object is located in a Portable Class Library. This is a convenient way of creating a common object model. When I make changes in the object model they are instantly updated in both my WPF and Metro applications.
The WPF App
The journey is almost complete. The data is in the neighboring kingdom and must be returned to the land of WPF. In the WPF application I set up a listener to notify me when any changes happen in the target folder. Here is the code that handles setting up the listener and handling the callback when that event happens:
The FileSystemWatcher is a great way to keep an eye on the neighboring kingdom. The watcher can be set to watch a specific location (Line 56), apply some notify filters (Lines 57-60), filter by file type (Line 63) and handle different events (Line 66). In this case we only care about the created event. Finally Line 68 informs the watcher to start raising events.
The OnChaged handler is responsible for taking the file, extracting the data, and handling the extracted data. It starts out by sleeping for 5 seconds (Line 73). This was necessary because when this callback fires the Metro application still had a handle on the file and I was getting an access exception. After that, the processing is pretty standard file access code for WPF applications. For this demo I write the data out to the screen (Line 81) but I could have easily persisted the data to a local database.
Here we can see the results. The Metro application is snapped and the WPF application is running filled. We can see that the data has made the round trip. Get the bytes and see for yourself.
Well, our journey is complete. The data has made it to Metro and back again. Like Bilbo in the Hobbit, it can now write its memoirs of the journey to the local database. The big server in the sky will read about the journey and shout the changes to all the lands. This happens the next time the devices has network connectivity. Obviously this journey would only be necessary should the user be offline for extended periods of time. If the user has connectivity then data should be shared through a common service infrastructure.
In the future hopefully navigating the different realms of Windows 8 will not be so complicated. Others have tried by hosting local service, which works during development but doesn’t in production. I sought out a path that utilized supported means. My goal was to use the facilities provided by both environments to come up with a solution that did not rely on me having to hack the system. There may be other more elegant solutions and I may seek them out when I have time.
Get the code bits here.
A couple of days ago Microsoft announced that “Metro” was a bad word. Their explanation is that Metro was a code word but rumor has it they were getting sued for copyright infringement. Either way I decided to keep using Metro for this post in order to be consistent with part 1. I will remove the word Metro from my vocabulary in future posts.
Another method I’ve seen discussed (e.g. http://www.infoq.com/news/2011/09/Metro-Protocols ) is using a custom protocol handler (similar to “http://” or “ftp://”). You can’t pass as much data via the URL, but it doesn’t require the file being created in the Documents folder.
Thanks for the comment. Using protocol activation does allow you to launch applications and pass a small amount of data as query string parameters. I have not seen any examples where large amounts of data have been passed. In my example you can pass whole object graphs of data. The data can come from a local database that is being used by a legacy desktop application. The data can then be manipulated by a Metro application and returned. For this case I don’t think that protocol activation will work.