Showing posts with label DotNet. Show all posts
Showing posts with label DotNet. Show all posts

Tuesday, September 01, 2009

Desklighter Update: Beta 2 with more customization options

The latest version of the Desklighter tool is now available for free download from IdentityMine Blendables Labs: http://blendables.com/labs/Desklighter/Default.aspx

 

desklighterbutton_white

“Desklighter is a windows utility that creates standalone windows applications from Silverlight xap files. Desklighter helps you in sharing your Silverlight applications as independent executables without having to worry about the hosting infrastructure. Unlike Silverlight Out-of-Browser(OOB) applications that run only on the installed computer, executables created by Desklighter are truly portable.”

See some sample games and demos created using Desklighter at http://sites.google.com/site/silverlightoffline

This new version of Desklighter has a settings panel providing more options to customize the executable application window. The settings available are Height and Width to control default application window size, border type (Re-sizable, fixed, none), application icon, background color, and window title. If the Silverlight application is expecting initial parameters, that can be supplied as well. It also supports transparency and it is possible to create custom shaped Silverlight standalone applications by setting the Background as 'Transparent' and choosing the 'No Border' option.

The recently released Silverlight 3.0 Out-of-Browser (OOB) feature opens up a lot of new scenarios as explained by Ashish Shetty. It surely is a great feature and will evolve to provide more options with upcoming releases of Silverlight. But it doesn’t help you in making your application portable. OOB helps in storing a hosted Silverlight application onto your desktop for running it from outside the browser. These applications will run only from the systems where they were installed.

However, applications created using Desklighter can be copied to another computer and it will work from it without any issues. If the computer doesn’t have Silverlight installed, the application will show a banner (default ‘No Silverlight’ experience) prompting the user to download and install the Silverlight plug-in.

Note that Desklighter is best suited for making already existing self contained Silverlight applications (where all the dependent resources are available within the xap file) portable. Examples include games, demos, proof-of-concepts, presentations, electronic brochures, tools and utilities.

Tuesday, August 18, 2009

Silverlight 3 Offline / OOB/ Out Of Browser Feature

Introduction

It is possible to configure Silverlight-based applications so that users can install them from their host Web pages and run them outside the browser. This feature is known by the name ‘OOB’ or ‘Out-of-Browser’ support, and sometimes just ‘Offline’ support.

Try a sample online or download the source code.

Configuration

  • Go to the Project Properties window (Right click on the Silverlight project in Visual Studio 2008 and choose ‘Properties’).
  • On the ‘Silverlight’ tab, select ‘Enable running application out of the browser’.
  • Click on the ‘Out-of-Browser Settings…’ button.
  • Fill or change the details like Window Title (Appears in the title bar of the out-of-browser application window), Width and Height (Indicates the dimensions of the out-of-browser application window; default is 800x600), Shortcut name (Appears in the out-of-browser installation dialog box and on the installed application shortcut or shortcuts), and Download description (Appears as a tooltip on the installed application shortcuts). Also assign application icon in a set of standard sizes (The operating system chooses the most appropriate icon to display in the installation dialog box, the application window, Windows Explorer, and Windows taskbar/Macintosh dock bar). These icons must be ‘png’ files and need to be added to the project initially with ‘Build Action’ set as ‘Content’. Optionally, 'Enable GPU Acceleration' can be turned on for graphics rich applications to enhance graphics performance by using hardware acceleration.


The values in the ‘Out-of-Browser Settings’ dialog box is used to generate an ‘OutOfBrowserSettings.xml’ file located in the project Properties folder. Any changes to this file are reflected in the designer. This file is used to populate the application manifest (AppManifest.xaml) with the specified values.
<OutOfBrowserSettings ShortName="MySloob Application" 
                      EnableGPUAcceleration="False" 
                      ShowInstallMenuItem="True">
  <OutOfBrowserSettings.Blurb>MySloob Application on your desktop; at home, at work or on the go.</OutOfBrowserSettings.Blurb>
  <OutOfBrowserSettings.WindowSettings>
    <WindowSettings Title="MySloob Application" Height="400" Width="600" />
  </OutOfBrowserSettings.WindowSettings>
  <OutOfBrowserSettings.Icons>
    <Icon Size="16,16">Icons/MySloob16.png</Icon>
    <Icon Size="32,32">Icons/MySloob32.png</Icon>
    <Icon Size="48,48">Icons/MySloob48.png</Icon>
    <Icon Size="128,128">Icons/MySloob128.png</Icon>
  </OutOfBrowserSettings.Icons>
</OutOfBrowserSettings>
Installation
When an application is properly configured for OOB, a new right-click menu option will be available as ‘Install <ApplicationName> Application onto this computer…’. Clicking on this will launch the installer dialog where the user can choose to create shortcuts on Start menu and Desktop. When ‘OK’ is clicked, the application will be installed to the local computer and it will be launched in a new application window. ‘Remove this application…’ right-click menu will now be available within this application to uninstall it from the computer.




Internals
If you look at the installed application’s shortcut properties, you will see that the target points to ‘C:\Program Files\Microsoft Silverlight\sllauncher.exe 1527765212.localhost’.

If you search for that random number (in my case: 1527765212) in Windows explorer, you will find a folder like this:

C:\Users\<user.name>\AppData\LocalLow\Microsoft\Silverlight\OutOfBrowser\1527765212.localhost

sllauncher.exe is the ‘Microsoft Silverlight Out-of-Browser Launcher’ application that gets installed along with Silverlight. It is a win32 application that loads the Silverlight application in its own browser host.

When you install a Silverlight OOB application, the XAP file is downloaded to the local computer and is stored in a folder within the user’s local app data called as ‘offline application cache’. The folder is named with a unique AppId which consists of a random number and the source of origin of the application (in this case: localhost). This folder will also have the application meta data and an index.html which has an object tag to load the Silverlight application.

sllauncher.exe takes this AppId (Examples: 1527765212.localhost, 1930341777.wayfarer.bizhat.com) as a parameter and then sets its window according to the metadata available in the specified offline application cache. It then loads the index.html in its browser host which in turn will display the Silverlight application.
metadata:
ShortcutName=MySloob Application
Name=MySloob Application
Title=MySloob Application
Description=MySloob Application on your desktop; at home, at work or on the go.
AppID=1527765212.localhost
RuntimeVersion=3.0.40624.0
FinalAppUri=file:///C:/Temp/MySloob/MySloob/Bin/Debug/MySloob.xap
OriginalSourceUri=file:///C:/Temp/MySloob/MySloob/Bin/Debug/MySloob.xap
SourceDomain=localhost
WindowHeight=400
WindowWidth=600
EnableGPUAcceleration=False
TrimmedName=MySloob Application
TrimmedTitle=MySloob Application
TrimmedSourceDomain=localhost
CustomIcon=1
LaunchPath=C:\Users\sameer.thiruthikad\AppData\LocalLow\Microsoft\Silverlight\OutOfBrowser\1527765212.localhost\index.html

index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" >
  <!-- saved from url=(0014)about:internet -->
<head>
  <style type='text/css'>
    html, body { height: 100%; overflow: auto; }
    body { padding: 0; margin: 0; }
    #silverlightControlHost { height: 100%; }
  </style>
</head>
<body scroll="no" onload="document.getElementById('_sl').focus()">
    <div id="silverlightControlHost">
      <object id='_sl' data="data:application/x-silverlight," type="application/x-silverlight" width="100%" height="100%">
          <param name="source" value="offline://1527765212.localhost"/>
          <param name="background" value="White"/>
          <param name="enableGPUAcceleration" value="False"/>
          <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
          </a>
      </object>
      <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>
</body>
</html>

Sample Application

There are a set of classes and methods available in Silverlight to install an application through code, to check for updates, to determine network status, etc. These are illustrated through the sample below:

XAML:
<Grid x:Name="LayoutRoot"
          Background="Beige">
        <StackPanel  HorizontalAlignment="Center">
            <TextBlock Text="Welcome to 'MySloob' - A sample Silverlight Out-Of-Browser Application!"
                       HorizontalAlignment="Center" />
            <TextBlock x:Name="uxDescription"
                       Text="()"
                       HorizontalAlignment="Center" />
            <Button x:Name="uxInstall"
                    Margin="20"
                    Height="50"
                    Width="200"
                    Content="Install Me"
                    Click="uxInstall_Click" />
            <Ellipse Height="100"
                     Width="{Binding ElementName=uxSlider,Path=Value}">
                <Ellipse.Fill>
                    <LinearGradientBrush EndPoint="0.5,1"
                                         StartPoint="0.5,0">
                        <GradientStop Color="Orange"
                                      Offset="0" />
                        <GradientStop Color="Red"
                                      Offset=".5" />
                        <GradientStop Color="Yellow"
                                      Offset="1" />
                    </LinearGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <Slider x:Name="uxSlider"
                    Margin="25"
                    Width="300"
                    Value="200"
                    Minimum="100"
                    Maximum="300" />
            <Button x:Name="uxCheckUpdate"
                    Height="50"
                    Width="200"
                    Content="Check Update"
                    Click="uxCheckUpdate_Click" />
            <TextBlock x:Name="uxOOBStatus"
                       Margin="0,25,0,0"
                       Foreground="Blue"
                       Text="OOB Status"
                       HorizontalAlignment="Center" />
            <TextBlock x:Name="uxInstallStatus"
                       Foreground="Brown"
                       Text="Install Status"
                       HorizontalAlignment="Center" />
            <TextBlock x:Name="uxNetworkStatus"
                       Foreground="Black"
                       Text="Network Status"
                       HorizontalAlignment="Center" />
            <TextBlock Text="Last Modified: 2009-August-18, 05:00 PM IST by Sameer C Thiruthikad"
                       HorizontalAlignment="Center" />
        </StackPanel>
    </Grid>
C# Code:
public MainPage()
{
    InitializeComponent();

    UpdateUI();
    Application.Current.InstallStateChanged += new EventHandler(app_InstallStateChanged);
    Application.Current.CheckAndDownloadUpdateCompleted += new CheckAndDownloadUpdateCompletedEventHandler(app_CheckAndDownloadUpdateCompleted);
    System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += new System.Net.NetworkInformation.NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
}

private void uxInstall_Click(object sender, RoutedEventArgs e)
{
    try
    {
        Application.Current.Install();
    }
    catch (InvalidOperationException)
    {
        MessageBox.Show("The application is already installed.");
    }
}

void app_InstallStateChanged(object sender, EventArgs e)
{
    UpdateUI();
}


private void uxCheckUpdate_Click(object sender, RoutedEventArgs e)
{
    Application.Current.CheckAndDownloadUpdateAsync();
}

void app_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
{
    if (e.UpdateAvailable)
    {
        MessageBox.Show("An application update has been downloaded. Please restart.");
    }
    else
    {
        MessageBox.Show("There is no update available.");
    }
}

void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
    UpdateUI();
}

private void UpdateUI()
{
    if (Application.Current.InstallState == InstallState.Installed)
    {
        this.uxInstall.IsEnabled = false;
    }
    else
    {
        this.uxInstall.IsEnabled = true;
    }

    this.uxOOBStatus.Text = "OOB Status: " + Application.Current.IsRunningOutOfBrowser.ToString();
    this.uxInstallStatus.Text = "Install Status: " + Application.Current.InstallState.ToString();
    this.uxDescription.Text = "(" + Deployment.Current.OutOfBrowserSettings.Blurb + ")";
   
    bool online = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

    if (online)
    {
        this.uxNetworkStatus.Foreground = new SolidColorBrush(Colors.Green);
        this.uxNetworkStatus.Text = "Network Status: Online";
    }
    else
    {
        this.uxNetworkStatus.Foreground = new SolidColorBrush(Colors.Red);
        this.uxNetworkStatus.Text = "Network Status: Offline";
    }
}
Try this sample online or download the source code.

Thursday, May 14, 2009

Microsoft Surface Applications - Deployment and Object Routing

Continued from: Microsoft Surface Tagged Objects and Tag Visualizations

When users interact with a Microsoft Surface unit, they launch the applications from Launcher.  Launcher is the menu that displays the applications that are available to users in a horizontal interactive strip.

surfacelauncher
 As part of deploying the Surface application, we must register it with Surface so that it is available in the Launcher. This is done by copying the application’s xml file to the Surface’s program data folder (%PROGRAMDATA%\Microsoft\Surface\Programs).

This application xml file is created by default when the Visual Studio project template is used. Otherwise, we can create a normal xml file with the file name equivalent as the project (executable) name and with the following tags.
<?xml version="1.0" encoding="utf-8" ?>
<ss:ApplicationInfo
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ss="http://schemas.microsoft.com/Surface/2007/ApplicationMetadata">
  <Application>
    <Title>My Surface App</Title>
    <Description>This is a sample Surface application.</Description>
    <ExecutableFile>%ProgramFiles%\MyCompany\MyApp\MyApp.exe</ExecutableFile>
    <Arguments></Arguments>
    <IconImageFile>%ProgramFiles%\MyCompany\MyApp\Resources\icon.png</IconImageFile>
    <Preview>
      <PreviewImageFile>%ProgramFiles%\MyCompany\MyApp\Resources\iconPreview.png</PreviewImageFile>
    </Preview>
    <Tags>
      <ByteTag Value="C0">
        <Actions>
          <Launch />
        </Actions>
      </ByteTag>
    </Tags>
  </Application>
</ss:ApplicationInfo>
The <Application> tag specifies that this is a normal Surface application. Other options are <AttractApplication> for attract mode (similar to screen saver) applications and <ServiceApplication> for apps that run in the background and does not have a UI.

The <Title> is displayed on the Launcher all the time, and <Description> is displayed when the application is selected from the Launcher. <ExecutableFile> specifies the path to the actual application exe. If the application is accepting any command line arguments it can be supplied through <Arguments> tag. <IconImageFile> specifies the png image to be displayed in the Launcher as application icon and <Preview> specifies the image to be displayed when the application is selected in the Launcher. This can be a bigger static image(<PreviewImageFile>) or a slideshow of images(<SlideshowImageFile>) or a movie (<MovieFile>).

The <Tags> specify the tags used by the application and <Launch> is used to specify that the particular tag value is used for object routing (which is discussed later).

To summarize the deployment steps again:
  • Build your Surface application in Release mode.
  • Copy all the files from the build folder to any location in the Surface computer (typically %ProgramFiles%\CompanyName\ApplicationName\).
  • Make sure that this path is specified in the Application’s xml file.
  • Copy the Application’s xml file to (%PROGRAMDATA%\Microsoft\Surface\Programs folder.
That’s all to it and the application will now be available in the Launcher for the user to see and launch.

Tagged Object Routing
On 2009-May-10, Microsoft released its first Service Pack (SP1) to Surface 1.0 with lots of new features and improvements. Read about them at official Surface blog.

Object Routing is one of the new SP1 features that enable the developer to configure tagged objects which can open applications without using Launcher. The tagged object can be placed anywhere on the Surface interface (attract applications, other non-registered applications or the Launcher) to bring up the list of applications that are registered with that tag. The applications will appear as tiny bubbly icons that smoothly pops up from the object and can be launched by touching them.

surfaceobjectrouting 
To enable the object routing for an applications:
  • Specify the required type of tag (Byte/Identity) within the <Tags> section of the application’s xml file and specify its value and have the <Actions> as <Launch>.
<ByteTag Value="C0">
  <Actions>
    <Launch />
  </Actions>
</ByteTag>
or

<IdentityTag Series="4245A8E4901C2C0B">
  <Actions>
    <Launch /> 
  </Actions>
</IdentityTag>

I have used an example value of C0 for Byte tag and 4245A8E4901C2C0B for Identity tag.
  • Create a new registry key using this tag value under TagInfo section as below:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\TagInfo\v1.0\ByteTags\C0
or

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\TagInfo\v1.0\IdentityTags\4245A8E4901C2C0B
  • Add the following String Value items on this key
    • Text : ‘object routing card title’.
    • BoundingBoxWidth : ‘3.25’.
    • BoundingBoxHeight : ‘2.125’.
    • PhysicalCenterOffsetFromTagX : ‘0’.
    • PhysicalCenterOffsetFromTagY : ‘0’.
    • OrientationOffsetFromTag : ‘0’.
This specifies the size of tagged object (business card size is 3.25 x 2.125 inches) and the location of the tag within this object (Zero means there is no offset from the center of the object; the tag is exactly on the center of this business card sized object)

Note that the other registry settings (enabled by default) to enable Object Routing (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0\Shell\EnableObjectRouting ) must be set as well.

That’s all the settings we need to do to get object routing work. Now if you place a tag with the specified value, all the applications that have this tag value in their xml file registered will popup from this object.

If you have done everything right, and still its not working as expected, refer the event log (run the command eventvwr) and navigate to Applications and Services Logs/Microsoft/Surface/Shell/Operational for any possible warnings or errors. Chances are that there is some error in the application's xml file or the registry settings. A sample warning (when the required registry entry is not present) looks like below:
The application info file C:\ProgramData\Microsoft\Surface\Programs\Macroni.xml refers to tag 29EB049F73061803, however, some configuration information for 29EB049F73061803 is missing from the registry. The default value '2.125' will be used for the missing setting.
Path to the tag's missing configuration setting in the registry:
HKEY_LOCAL_MACHINE\Software\Microsoft\Surface\TagInfo\v1.0\IdentityTags\29EB049F73061803\BoundingBoxHeight
Happy coding!

Thursday, September 11, 2008

Desklighter Update: Beta 1.1 with 64 bit support

Thanks to one user (aquaseal) who reported that Desklights are not displaying the Silverlight content on 64 bit systems. We have fixed this issue and a new version of Desklighter (Beta 1.1) is now available for download from Blendables Labs.

Another update we released with this version is the icon feature for Desklights. Earlier, Desklights were showing the default windows executable icon and now it is changed to a Desklight exe icon.

Update: http://ctlabs.blogspot.com/2009/09/desklighter-update-beta-2-with-more.html

Monday, September 01, 2008

Desklighter – carry the light along

Today is a great day for me. At IdentityMine, I’ve been working on a software tool named as ‘Desklighter’ since some time back and now it is released to public as a free beta version through our product website’s labs section at http://blendables.com/labs/Desklighter/Default.aspx.


Desklighter is a windows utility that can convert a Silverlight application into a standalone desktop application. The output from Desklighter is a single executable file that can display the Silverlight content on windows desktops without requiring a hosting server or a browser. Desklighter enables users to carry a Silverlight application off the web to wherever they need it.

Download Desklighter from here and try converting your Silverlight XAP files into windows exes.

The idea of taking the Silverlight application off the web into a portable single file executable opens up a whole new playing field. Now you will be able to carry your favorite Silverlight games from the web in a USB Flash drive to your friends who are not connected to internet. You can now share your exciting ideas materialized in Silverlight without having to worry about the hosting infrastructure. Your flashy Silverlight demo can now be taken to your customer for showcasing during a presentation. You can distribute your stylish e-brochure done in Silverlight in CDs to whomsoever you want. The possibilities are endless.

A Desklight (the EXE created using Desklighter) need to have the Silverlight plug-in (currently Silverlight 2 Beta 2) installed to run on windows desktops. Below is a screen shot of a sample Desklight. You can download more samples from http://sites.google.com/site/silverlightoffline.


Information about a Desklight including the Desklighter version used to create it can be found when executed from a command line with 'info' as the argument.


Another available command line argument is ‘debug’, which displays the Desklight’s server information while the Silverlight content is getting served. Use this if you see some issues while running a Desklight to know what is happening behind the screens.


Read the complete technology story behind Desklighter here.


The name ‘Desklighter’ was chosen to represent Desktop + Silverlight. My colleague Hariprashanth was the one who created all the graphics work for Desklighter. The logo is made up of four ‘D’s (representing Desklighter) with the windows logo colors (representing desktop).  Hari did an excellent work in giving it a stylish look.

I would like to thank all my colleagues here at IdentiyMine for extending their support and providing valuable feedback during the development of Desklighter. The wish list for the next version of Desklighter is growing,  thanks to the innovative ideas from them.

Please let us know what you think about this tool, and what you would like to see in its future versions.

Update - New Version Released: http://ctlabs.blogspot.com/2009/09/desklighter-update-beta-2-with-more.html

Wednesday, May 07, 2008

WPF Color Pad

Ever wanted to see the list of named colors available in WPF's System.Windows.Media.Colors? And fancied using it's hexa code to get the colors like 'Tomato' in your web page?

Here is a simple WPF Application called ColorPad that lists out all the named colors. Click on a color to see its hexa code value. Remember to remove the first two letters/digits that represents the transparency (Alpha value) if you are using this color in html pages.


The application can be downloaded from here.

The XAML Source Code:

<Window x:Class="ColorPad.Window1" Icon="ColorPad.ico"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ColorPad" Height="500" Width="300" WindowStyle="SingleBorderWindow" ResizeMode="NoResize">
<Window.Resources>
<DataTemplate x:Key="tempGrid">
<Rectangle Width="60" Height="20" Fill="{Binding Name}" Stroke="#FF000000"/>
</DataTemplate>
</Window.Resources>

<Grid x:Name="LayoutRoot" ShowGridLines="True">
<StackPanel Orientation="Vertical">
<TextBlock x:Name="uxTitle" Text="ColorPad Version 1.0.0" Width="210" TextAlignment="Center" />
<ListView Height="400" Width="210" Name="uxColorGrid">
<ListView.View>
<GridView x:Name="uxColorGridView">
<GridViewColumn Header="Color Name" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn CellTemplate="{DynamicResource tempGrid}" Header="Color" />
</GridView>
</ListView.View>
</ListView>
<TextBlock x:Name="uxFooter" Visibility="Collapsed" Width="200" Background="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<TextBox x:Name="uxColorCode" Width="210" TextAlignment="Center" />
</StackPanel>
</Grid>
</Window>


And the Code Behind in C#:

using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Collections.Generic;

namespace ColorPad
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();

uxColorGrid.ItemsSource = typeof(Colors).GetProperties();
uxColorGrid.SelectionChanged += new SelectionChangedEventHandler(uxColorGrid_SelectionChanged);
}

void uxColorGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PropertyInfo c = uxColorGrid.SelectedItem as PropertyInfo;
uxFooter.Text = c.Name;

SolidColorBrush scb = uxFooter.Background as SolidColorBrush;
uxColorCode.Text = scb.Color.ToString();
uxTitle.Foreground = uxFooter.Background;
}
}
}