A quick look at Silverlight 3: Running Outside the Browser

One of the big (huge? :-)) areas of Silverlight 3 is the ability for applications to run outside of the browser.

That is, an application that is running inside of the browser can be “detached” in order that it can then be run from a desktop shortcut or a Start Menu shortcut and it can be run without necessarily having a network connection and, also, in a window that makes it look like a regular desktop application rather than an application running inside of a browser.

In order to get “detached” the user has to make an explicit choice about the application – the application can’t just detach itself without the user noticing. If we take a simple “Hello World” application like this one below;

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <StackPanel x:Name="LayoutRoot" Background="White">
        <TextBlock
            x:Name="txtStatus" Text="Not Set" HorizontalAlignment="Center" Margin="10" />
        <Button
            Content="Click Me"
            Click="OnClicked"
            Margin="10"/>
    </StackPanel>
</UserControl>

with a little bit of code;

 public partial class MainPage : UserControl
  {
    public MainPage()
    {
      InitializeComponent();
      OnExecutionStateChanged(null, null);
      App.Current.ExecutionStateChanged += OnExecutionStateChanged;
    }
    void OnExecutionStateChanged(object sender, EventArgs e)
    {
      txtStatus.Text = App.Current.ExecutionState.ToString();
    }
    void OnClicked(object sender, RoutedEventArgs args)
    {
      App.Current.Detach();
    }
  }

and we then go ahead and run it in the browser then we’ll see a new right mouse menu;

image

which allows for the application to be detached and installed onto the local machine. However…you’ll notice that the menu option is greyed out right now.

Similarly, we can put code behind our button ( as far as I know, it needs to be code that runs in response to a direct user action like clicking a button ) and attempt to detach the application ourselves like we have in our handler;

    void OnClicked(object sender, RoutedEventArgs args)
    {
      App.Current.Detach();
    }

but it won’t work for the same reason that the right menu option is disabled – the application doesn’t yet have the supporting metadata to allow a detach. In order to provide metadata, we can edit our appmanifest.xml file to include as in;

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"

            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Deployment.Parts>

  </Deployment.Parts>

  <Deployment.ApplicationIdentity>

    <ApplicationIdentity

      ShortName="Mike’s Silverlight App"

      Title="Mike’s App Window">

      <ApplicationIdentity.Blurb>Mikes Application Blurb</ApplicationIdentity.Blurb>

      <ApplicationIdentity.Icons>

        <Icon Size="16×16">icons/16×16.png</Icon>

        <Icon Size="32×32">icons/32×32.png</Icon>

        <Icon Size="48×48">icons/48×48.png</Icon>

        <Icon Size="128×128">icons/128×128.png</Icon>

      </ApplicationIdentity.Icons>

    </ApplicationIdentity>

  </Deployment.ApplicationIdentity>

</Deployment>

Note: those icon files above are set to build as “Content” in Visual Studio and are embedded into the XAP and I’m not sure that you need all those icon sizes either – especially the 128×128,  I just threw them all in for safety 🙂

and then the right mouse menu becomes available to us;

image

and the button that we previously built raises the exact same dialog offering the user the option of taking the application outside of the browser and installing desktop and Start Menu shortcuts;

image

Note that’s the standard dialog – with my icon settings from above you would actually see my icon;

image

but as I hadn’t put a lot of work into my icon 🙂 I thought I’d better show the standard one here as well.

If I choose to click OK on the dialog then the application attempts to detach itself – as far as I’m aware this is purely to do with ensuring that the XAP is available locally and does not make an attempt to bring any other resources associated with the application to the local machine.

image

Note that a second “copy” of the application is now running in a window that doesn’t look like a browser window and note that my TextBlock has been updating as it captures the ExecutionStateChanged event hanging off the Application type and it knows ( both in the local and the original browser version ) that the application has been Detached.

I now have a desktop icon for the application;

image

and I have a Start Menu option for it;

image

If I run the application locally from one of these shortcuts then I get the “non-browser” experience;

image

and if I re-run the original application in the browser it shows the same “Detached” state;

image

Now, if I update the original application to have a fancy new red background;

image

and re-run the local application having deployed my new XAP to my web server – initially it shows the status of “Detached” and then it switches to “DetachedUpdatesAvailable” which is the point where I could tell the user that the application has been updated and perhaps prompt them to re-run the app;

image image

and when they re-run the application they get the new version that I dropped onto the server;

image

if I want to remove the application then I can use the right mouse menu on either a locally “detached” copy or a “web browser copy” running in a full browser window as in;

image

and if I take that menu option I end up with the locally “detached” version going away in the sense that the Start Menu option is gone, the desktop icon is gone and the status of the browser-based version goes back to “RunningOnline” rather than “Detached”.

image

Given that the App.Current.ExecutionState property returns Detached once an application has been detached regardless of whether you’re running the application in a browser or whether you’re running it as a locally detached application there’s a need for another flag to determine whether the application has been started in a browser or locally detached.

There’s a flag on Application called RunningOffline which looks to give you that true/false status – true if the application was started as a locally detached application and false if the application is running inside the browser.

In terms of what code actually runs the application when it’s offline – there’s a process in Program Files\Microsoft Silverlight\VERSION\ called sllauncher.exe which looks to take the name of the application and launch it – from a quick look with Reflector, it looks like this process is unmanaged so I don’t think there’s too much we can learn about what it’s doing internally but it’s worth stating that one of the roles of this launcher will be to preserve the security context of the original application such that if it came from domain foo.com then the application must run locally as though it was launched from foo.com.

It’s also worth noting that the detached functionality appears to depend on Isolated Storage and I’ve found that I need to have Isolated Storage switched on in Silverlight for an application to be detached – makes sense really.

This is one of a series of posts taking a quick look at Silverlight 3 – expect them to be a little “rough and ready” and that they’ll get expanded on as I’ve had more time to work with Silverlight 3.