Update: Part 2 Hot off the press
As most of you know Microsoft is about to release a new operating system. If you have not heard then you should crawl out from under the rock and embrace the future of Windows. With the new operating system they are releasing a new type of application. These Metro application deliver rich, immersive experience. One of the benefits that Microsoft keeps emphasizing is that with Windows 8 you have a full Windows operating system and a tablet operating system all in one device. You will be able to use the desktop applications you use today, while gaining access to a whole new set of apps. This type of device should be ideal for the enterprise.
Microsoft is pushing developers to develop enterprise application but they are tying their hands with a sandbox. These applications run in an extremely restrictive sandbox. The sandbox prevents Metro applications from accessing anything outside without jumping through hoops and user intervention. So there is no means to access the local database that my legacy application uses. In fact there is no interaction between a Metro application and a WPF application allowed.
What if you have a legacy desktop application that you want to enhance by providing some functionality through a Metro application. This post is about the adventure of going from a native application to the Metro world and back again. I will show you a path that you could take to reach total unity on your machine. There is no need to rewrite you legacy applications in order to support Metro but you may need to modify them. Let’s start down the path and see where it leads. In Part 1 we will make it half way but our adventure will only be successful if we make it back.
I tried to come up with a way to have my two applications work together to solve the business needs. This little POC takes a look at a way to achieve my goals in a way that doesn’t try to hack the system and is supported by Microsoft. I am sure there are other ways but this was simple to implement and did not violate the integrity of the sandbox in an unsupported way.
WinRT and .Net are two different technologies. Their libraries are incompatible. They do share many of the same API’s but they are usually in different namespaces. This makes it difficult to share a common object model. You could use other techniques like passing JSON back and forth but now you have to do double the work the maintain the object model in both environments. I wanted to minimize the maintenance of the application so I decided to create a Portable Class Library.
The Portable Class Library has been around for a while now as an out of band addition to Visual Studio. It allows you to select some target frameworks that you want your library to run on. It then restrict your development to a subset of API’s that are available in the selected frameworks. The resulting dll can be referenced in each framework without any recompilation. Here you can see my WinRT project and WPF project contain a project reference to my Portable Library.
In the portable library I can create my object model and have it stay in sync between the two frameworks. For this demo I created a person class to handle passing data back and forth. Here is the code of my person class, as you can see it is pretty basic:
The WPF App
Now I will build out a WPF application that will allow you to enter the first and last name and pass it to the Metro application. Here is the code from the MainWindow.xaml.cs
For this demo the UI is not important. You can check it out by downloading the code. Here you can see I am creating a person object, streaming that person object to a file and launching my Metro application by calling process start on the file I just created. In order for this to work your Metro application has to be the default application for that file type (more on that in a minute). I created my own file type extension in order to avoid collision with other file types on the system.
The Metro App
The key to making our integration scenario work is to enable the File Type Association declaration in our Metro application. The first step is to modify the application manifest to add the file type association declaration. You use this declaration to associate your application to different file types. You can associate with common file types like txt and png. You can also associate with a custom file type. That is what I am doing here.
Using the File Type Association declaration only notifies the operating system that this application can be associated with a file type. One of the tenants of Windows 8 is the user is in control. Going along with that you can’t take over being the default application for a specific type. So if you are working with a common file type then the user has to make your application the default application for any specific type.
Since our Metro application is the only one that associates with our file type it becomes the default application for that type. So when the WPF launches the file it saved in a new process our Metro application launches because it is the only one that can handle that type.
When your application is launched by a file activation the OnFileActivated method gets called. You override that method in the App.xaml.cs. For more information on file activation take a look at the MSDN documentation. The EventArgs for this method is where you first get access to the file(s) that caused the launch. Here is an example of overriding that method”:
In the OnFileActivated method I am passing the EventArgs on to the Activate method of our main page. Here is the code for that method.
The MainPage gets the file out of the EventArgs . Then the file is streamed in memory to a IRandomAccessStream which is then passed onto the DataContractSerializer where the person object is extracted. The results are displayed on the screen (again the UI is not important). Since we used the Portable Class Library the person object is the same in WPF and WinRT so the DataContractSerializer works just fine. Our journey is half done. Like Bilbo Baggins in the Hobbit, you have to make it back to enjoy the spoils of the adventure.
The person object has made the journey from WPF, where it was created, all the way to a Metro application, where it was consumed. In the next post we will take a look at what it takes to send a modified person object back to WPF. In this example we created the data in memory. This data could have easily come from a local database. This architecture allows us the ability to work with legacy desktop applications. It show that migrating to WinRT is not an all or nothing proposition. You can migrate functionality on your schedule.
You can download the code here.
Update: Part 2 Hot off the press