Hosting An Avalon Application in a Browser: More than just flipping a bit

I recently wanted to convert a project that ran as a standalone Avalon application into an application that was hosted in the browser.   This is a very cool feature of Avalon, such that there can be a seamless experience from surfing the web to encountering an Avalon application.  There are two seperate templates in VS: one for hosting in the browser and one for a standalone application.  But what if you already have a standalone application and want to turn it into something hosted in the browser?  It isn't hard, but it is more than just changing the <HostInBrowser> boolean to true in your .proj file (or .csproj or .vbproj file). 

 

The first gotcha I hit after changing the boolean to true surfaced when I navigated to the .deploy file in the browser. I used the file:// syntax and browsed to the .deploy on the harddrive as recommended in the readme.txt of the Avalon Browser Application template in Visual Studio. The application installed, but when it ran, a .dll was missing.  What happened?  I looked at the .manifest file and sure enough, the .dll that the .exe needed was nowhere in the .manifest file.  Why didn't the compiler add it?  The application ran fine when the .exe was launched, so what was different when going through a .deploy?  After poking around, I realized that the .dll wasn't signed and therefore the compiler step that creates the manifest simply skipped the .dll.  By signing the .dll, the manifest included it and I was good to go. But then I hit the second gotcha.

 

When I launched the app through the .deploy file in the browser, the browser kicked the UI out and launched a seperate window, completely defeating the purpose of running in the browser.  Why?  Because my application was coded up to use the <Window> element, which, by its very definition, doesn't run in a browser.  I had to change my top level element to be something else (Canvas, DockPanel, Pane, etc.).   I also had to change my start up file from Application to NavigationApplication and then change the StartingUp attribute to the StartupUri attribute, pointing at the .xaml file instead of an event.

 

But with those changes, I was good to go, and my application was now running in the browser!