Silverlight 3: What's New with Out of Browser

This is the fourth post in a series where I will be walking through some of the new features in Silverlight 3. I enjoyed reading Tim Sneath’s blog post, https://visitmix.com/Opinions/Whats-New-in-Silverlight-3 but as I read the post I kept saying cool, but how do I do it. So in these posts I will try to answer the “how do I” questions around the new features.

Let’s get started.

Out of Browser

Today the host for Silverlight applications is a web browser. The new out of browser feature in Silverlight 3 allows you to break free of the browser and run the application out of the browser. Your Silverlight Out of Browser (SLOOB) will have a link on the desktop or the start menu. This works for both Macs and PCs. This will cache the XAP locally, enabling you to launch the SLOOB even if you are offline. Of course this requires that the Silverlight developer code the application to detect offline status and work with data in isolated storage. Luckily Silverlight provides APIs that make this easy for the developer to be offline aware. The SLOOB applications will run with the same security sandbox as the browser and will auto-update when a new version is detected.

Create a new Silverlight project

In order to create Silverlight 3 projects you will need to install Visual Studio 2008, and the Silverlight 3 SDK and tools. Create a Silverlight C# project called "SLOOB" and accept the defaults which will create 2 projects in the solution.

Create the UI

The UI for this app will consist of a couple of labels to display some text and the online status of the application.

 <UserControl
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
    x:Class="SLOOB.MainPage" 
    Width="400" Height="300" Background="Bisque" mc:Ignorable="d">

    <Grid x:Name="LayoutRoot" Background="White">

        <controls:Label Height="44" Margin="32,8,48,0" VerticalAlignment="Top" 
                        Content="Out of Browser Test.&#xd;&#xa;" FontSize="20"/>
        
        <controls:Label x:Name="InstalledLabel" Margin="8,68,8,0" 
                        Content="Installed Status" FontWeight="Bold" FontSize="24" 
                        VerticalAlignment="Top" Height="44"/>
        
        <controls:Label x:Name="OOBLabel" Margin="8,112,8,144" 
                        Content="Out of Browser Status" FontWeight="Bold" FontSize="24"/>
        
        <controls:Label x:Name="OnlineLabel" Margin="8,0,8,100" 
                        Content="Online Status" FontWeight="Bold" FontSize="24" Height="44" 
                        VerticalAlignment="Bottom"/>
        
        <Button x:Name="InstallButton"
            Content="Install Locally" 
            Click="OnClicked" 
            Margin="0,0,17,8" Width="100" Height="30" 
            HorizontalAlignment="Right" VerticalAlignment="Bottom" 
            d:LayoutOverrides="Width, Height"/>

    </Grid>
</UserControl>

Enable Out of Browser

You will need to turn on the out of browser feature by editing the appmanifest.xml file (located in the Properties folder in your Visual Studio project)

By default the config file has the out of browser section (Deployment) commented out.

 <Deployment xmlns="https://schemas.microsoft.com/client/2007/deployment"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
>
    <Deployment.Parts>
    </Deployment.Parts>

    <!-- Uncomment the markup and update the fields below to make your application offline enabled
    <Deployment.ApplicationIdentity>
        <ApplicationIdentity 
            ShortName="Out of Browser Silverlight Application" 
            Title="Window Title of Your Silverlight Application">
            <ApplicationIdentity.Blurb>Description of your Silverlight application</ApplicationIdentity.Blurb>
        </ApplicationIdentity>
    </Deployment.ApplicationIdentity>
    -->
</Deployment>

Uncomment the commented node to turn on out of browser support.

 <Deployment xmlns="https://schemas.microsoft.com/client/2007/deployment"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
>
    <Deployment.Parts>
    </Deployment.Parts>

    <!-- Uncomment the markup and update the fields below to make your application offline enabled
    -->
    <Deployment.ApplicationIdentity>
        <ApplicationIdentity 
            ShortName="Out of Browser Silverlight Application" 
            Title="Window Title of Your Silverlight Application">
            <ApplicationIdentity.Blurb>Description of your Silverlight application</ApplicationIdentity.Blurb>
        </ApplicationIdentity>
    </Deployment.ApplicationIdentity>
</Deployment>

Running the app you will now see that the right-click menu is enabled.

image

Select ok on the install dialog.

image

Detect Installed Status

You can detect if the app is installed locally. You can check the ExecutionState property of the App object. I found the state of RunningOnline or Detached to be confusing. This is the installed state of the app not the network connectivity status of the application.

 //Is the SL App installed
if (App.Current.ExecutionState == ExecutionStates.RunningOnline)
{
    InstalledLabel.Content = "App is NOT Installed locally";
}
else
{
    InstalledLabel.Content = "App is Installed locally";
}

You can listen for the ExecutionStateChanged event. This will fire when the app is installed or uninstalled.

 App.Current.ExecutionStateChanged += OnExecutionStateChanged;

Detect the In Browser or Out of Browser instance

The instance of the application you are running is important you need to be aware of which instance you are running. For example the OOB instance will not have access to the HTMLBridge of the webpage. This is easy enough to detect. The App object has a Boolean property called RunningOffline. If this is true you are in the OOB instance.

 //Which instance is running
if (App.Current.RunningOffline)
    OOBLabel.Content = "App is Out of Browser";
else
    OOBLabel.Content = "App is IN Browser";

Detect Online Status

It is important to understand when you are connected and when you are offline. This as it turns out is a hard problem. There is a great talk about this by Peter Smith.

Offline Detection in Silverlight 3 : https://videos.visitmix.com/MIX09/T78M

To know if you are online requires answering 2 questions:

1. Can you connect to your server?

2. Have you validated the response?

Debugging your SLOOB

Debugging your OOB instance of the app requires that you manually attach to the process hosting the app, sllauncher.exe. Once you attach you can debug as you normally would.

image

 

All code

Here is the entire code file.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Net.NetworkInformation;

namespace SLOOB
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            SetStatusLabels();

            //detect install state
            App.Current.ExecutionStateChanged += OnExecutionStateChanged;

            //detect online/offline
            NetworkChange.NetworkAddressChanged += 
                OnNetworkChange;
        }

        void OnExecutionStateChanged(object sender, EventArgs e)
        {
            SetStatusLabels();
        }

        //fired whenever network connectivity changes
        void OnNetworkChange(object sender, EventArgs e)
        {
            SetStatusLabels();

        }

        void OnClicked(object sender, RoutedEventArgs args)
        {
            if (App.Current.ExecutionState == ExecutionStates.RunningOnline)
                App.Current.Detach();
        }

        void SetStatusLabels()
        {
            //Is the SL App installed
            if (App.Current.ExecutionState == ExecutionStates.RunningOnline)
            {
                InstallButton.IsEnabled = true;
                InstalledLabel.Content = "App is NOT Installed locally";
            }
            else
            {
                InstallButton.IsEnabled = false;
                InstalledLabel.Content = "App is Installed locally";
            }

            //Which instance is running
            if (App.Current.RunningOffline)
                OOBLabel.Content = "App is Out of Browser";
            else
                OOBLabel.Content = "App is IN Browser";

            //Are we connected?
            if (NetworkInterface.GetIsNetworkAvailable())
                OnlineLabel.Content = "Network is available";
            else
                OnlineLabel.Content = "Network is NOT available";


        }

    }
}