| Comments

I’ve been promising this for a while and I’ve ranted about creating good installation experiences for Silverlight applications before as well here and here.  Well, our team rallied and created some new guidance and sample code to provide for you to implement the best possible experience.  The guidance whitepaper can be found on the Silverlight Community Site in the whitepapers section and includes:

  • Documentation for defining a good user experience
  • Sample code for media applications
  • Sample code for non-media applications
  • Sample code for implementing various states: not installed, upgrade needed, browser restart detection

The sample code is easy to understand and was templated so that you could change things to your brand/application.  The media sample can be dropped into your Expression Encoder templates easily and does a lot of the magic for you without having to thing (i.e., getting sizes of media, snapshot of media for image, etc.).

Hopefully this will help you understand the process more and provide you with the information (and code) you need to complete the best possible experience in your site.  You’ve spent the time developing your application, make sure you spend the time delivering the best install experience for those who may not have Silverlight yet.

Download the whitepaper and code today.

Hope this helps!

| Comments

Yesterday a minor update to the Silverlight 2 runtime was released.  You may see terms of “GDR 1” floating around.  That’s pretty much an internal term at Microsoft referred to as “general distribution release” – yeah, I know we have a lot of random terms.  Think of it just as an incremental update.  If you are curious for Silverlight’s entire release history, you can view that here.

So what’s in it?  Well, nothing earth shattering if you were expecting feature updates.  There were some needed fixes based on customer feedback that we included in this update (which is version 2.0.40115.0).  Basically I would bucket it into a simple list for you:

  • Various accessibility fixes relating to UIAutomation
  • Fixes for certain anti-virus vendors scanning algorithms
  • Much needed fix for OSX platform when users modify their font locations (i.e., people with font management tools usually)
  • Bug in IsolatedStorage quota increasing when the user’s display language is set to one that Silverlight has not been localized to

That’s about it…no new controls, nothing suddenly going to make you amazed and shocked.  But it was a needed release to fix these issues. 

So what should you do?  Depends. 

If you are a consumer…

You really shouldn’t need to do anything unless you are specifically experiencing one of the issues above.  Web developers using Silverlight and needing their user’s to have this update will update their site and let you know.  There isn’t a huge need to rush out as an end-user and download the update.  Besides, if you have it configured to automatically update, then in due time you’ll get the update through that mechanism and won’t have to do anything.  If you absolutely want to be on top of things, then feel free to grab the latest updated runtime by visiting the download link.

If you are a developer…

If you are directly affected by the changes above then you should update your application.  There are really two things you need to do:

For the latter note this is a simple change.  Update your “MinRuntimeVersion” attribute in your hosting page/content to ensure that end users have the latest runtime version for your application.  Again, you should only really need/want to do this proactively if you (or your users) are directly affected by the updates in this release!  Here’s how you’d do it.

NOTE: Even though you update the developer runtime the Visual Studio project templates are not updated to set the default runtime version to the updated version so each new Silverlight project using those templates will still reference minRuntimeVersion=”2.0.31005.0” – if you want to change that you can modify the template.

UPDATE: How to modify the default value of the template

I’ve received some errors myself after changing this, so while it sounded like a good idea :-), I can’t recommend altering this reg value to the updated version – if I find out why, I’ll post here.

I got some questions about exactly how you would get the default web templates to change the generated test pages to emit the updated version number.  Since these are pages in a web project and not the Silverlight project, it isn’t easily found.  In fact, that value gets pulled from a registry setting.  The setting is at (removing the Wow6432Node if you are not on 64-bit Windows):

   1: [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Silverlight\v2.0\ReferenceAssemblies]
   2: "SLRuntimeInstallVersion"="2.0.40115.0"

and you need to change the value to match what you want that to be.  Again, this is not a required step at all.

As a reminder, messing with your registry can be dangerous if you have no idea what you are doing.  Backup your reg keys, don’t blame me if something goes wrong :-).

If you are using the ASP.NET Silverlight control you’d modify the MinimumVersion and AutoUpgrade attributes:

   1: <asp:Silverlight ID="Xaml1" AutoUpgrade="true" runat="server" 
   2:                 Source="~/ClientBin/SilverlightApplication3.xap" 
   3:                 MinimumVersion="2.0.40115.0" Width="100%" Height="100%" />

If you are using the <object> tag instantiation you’d modify the minRuntimeVersion and autoUpgrade attributes in the <object> tag for your Silverlight application:

   1: <param name="minRuntimeVersion" value="2.0.40115.0" />
   2: <param name="autoUpgrade" value="true" />

If you are using Silverlight.js to create the object you’d modify the version attribute when passing it in to the properties parameter of the createObject function (sample):

   1: Silverlight.createObject(
   2:             "ClientBin/SilverlightApplication1.xap",  // source
   3:             silverlightControlHost,  // parent element
   4:             "slPlugin",  // id for generated object element
   5:             {
   6:                 width: "100%", height: "100%", background: "white", 
   7:                 version:"2.0.40115.0"
   8:             },
   9:             { onError: onSLError, onLoad: onSLLoad },
  10:             "param1=value1,param2=value2", 
  11:             "context"    // context helper for onLoad handler.
  12:         );

That’s it!  Hope this helps.  The team is diligently working on Silverlight 3!

| Comments

First a congratulations to the Moonlight team for reaching their official release of 1.0!  Miguel and team have done a great job providing parity with Silverlight 1.0 and should be proud of their accomplishments.  Miguel, when is Moonlight 2 coming out :-) -- no rest!!

But seriously, this is a good accomplishment for the ecosystem.  Last month I wrote and recorded my experience of the Moonlight installer/rendering on an OpenSUSE environment.  What this demonstrated was that we’d integrated the Moonlight redirection/installer into the server-side installer detection from Microsoft.  Users on Linux visiting a Silverlight 1.0 application and not having the plugin would be directed to the Moonlight installer, using the same install link that other Silverlight applications currently leverage.  I think this shows great partnership to both teams to acknowledge and integrate that process.

Today, I updated the user agent detection script for Silverlight to also accommodate this release.  For those who don’t know, there are two helper scripts for Silverlight developers you can leverage:

  • Silverlight.js – this script helps to detect if the plugin is installed and if so, create’s the appropriate <object> tag representation.
  • Silverlight.supportedUserAgent.js – this script is also a helper script that can be used with Silverlight.js or alone.  The purpose of this script is to do some pre-checking to see if the browser/platform combination (based on the reporting User Agent string of the browser) will support Silverlight.

It is the second script that I’m referring to.  The updated release on the release site for the script (2.0.40211.0) now includes checking for Linux and reporting correctly.  Using this script is as simple as:

   1: var canSilverlightRun = Silverlight.supportedUserAgent("2.0");

This code above is basically asking: I’ve got this combination, is this version of Silverlight going to be supported?  This helper can be used by developers to pre-check if Silverlight can run on the platform of the user. 

If you are using the UA detection script, you’ll want to update it to the latest version if you have a Silverlight 1.0 solution and want to expand to Linux users.  That is the only change in this update.  No changes to Silverlight.js have occurred as a result of this, as remember, that only checks if the desired version is installed on the user machine.

If you want to play around with some settings, you can visit a quick-and-dirty page I created that uses both scripts and reports the results (Version Supported reports Silverlight.isInstalled, and UA Supported reports Silverlight.supportedUserAgent).  Hope this may help.

Hey what about this Google Chrome hack you mentioned?

Officially Google Chrome is not a supported browser, but most (your mileage may vary) Silverlight applications run.  Since the detection scripts are Ms-PL licensed, you’re welcome to change them to fit your needs.  The official copy on the release site will map to the supported matrix for Silverlight for now.  If you want to add support for Google Chrome, here’s what you’d do.

On line 93 in Silverlight.supportedUserAgent.js, insert this line:

   1: else if (ua.indexOf('Chrome') >= 0) {
   2:     slua.Browser = 'Chrome';
   3: }

Before the Safari check is important because Chrome’s user agent reports Safari in it as well as Chrome.  Then you will have Chrome detection working in your script.  Again, only if you need/want it.  We continue to evaluate the browser support matrix for Silverlight and before you ask – no decisions have been made just yet to change the current supported matrix.

Hope this helps!  Congratulations Moonlight team!

| Comments

Over the holiday this past week I got a ping from Scott Cate about some Silverlight media questions, namely a player and Silverlight Streaming.  The gist of the conversation was that the Encoder 2 SP1 templates and the SLS Plugin don’t play nice together (yet).  I know that the team has been testing some updates to the plugin for uploading Silverlight 2 templates to SLS, but for now if you tried to do that you’ll get a random error message that won’t make sense to you (something along the lines of template not found).

After talking with Scott and understanding his scenario more (media formats and CDN hosting – note: CDN=Content Delivery Network - specifically) we, well I, decided it might be a good idea to use an alternate player right now.  Of course I suggested the one that Joel and I worked on, but there are also many other out there.  I should also point out that the Encoder 2 SP1 templates also include a fully functional Silverlight 2 player with source code that you can use.  Scott took my player as a start (not sure if it will be the final one he uses) and we went to chatting about the implementation.  I first told him he could still use SLS and just upload the XAP, etc. but remembered that SLS doesn’t fully support an easy implementation of initParams just yet (it can, but a little workaround-ish right now).  After learning of the initParams, Scott wanted to host the player on his CDN and just pass in the media URI as the param (exactly what our player is built for).

I pointed to the instructions on the SL2VideoPlayer CodePlex site and we started implementing.  So Scott was going to have his pages delivered from his CMS system on his site (let’s call it foo.com) and have the Silverlight application delivered from his CDN (let’s call that mycdn.com).  Then the media was going to be hosted on another CDN (Silverlight Streaming).  We had three networks in play here: foo.com, mycdn.com and Silverlight Streaming.  In his site delivered by his CMS system he’d have the object tag for the player implemented something similar to:

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="640" height="480">
   2:         <param name="source" value="http://mycdn.com/myaccount/VideoPlayerM.xap"/>
   3:         <param name="background" value="white" />
   4:         <param name="initParams" value="m=http://silverlight.live.com/accountid/Bear.wmv" />
   5:                <param name="minruntimeversion" value="2.0.31005.0" />
   6:         <a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">
   7:              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:         </a>
   9:     </object>

Note that the source for the Silverlight application is a full URI to the CDN endpoint of the XAP file.  Also note the initParams which would point to the video file hosted on Silverlight Streaming (this isn’t the real URI, just a sample).  When rendered, we saw the Silverlight default loader (%age orb) and then a white screen – nothing.  WTF?!  Loading up my favorite tool for Silverlight network debugging we saw the XAP being delivered and loaded, but then the media file was not.

I then remembered that I may have forgot to tell Scott that any remotely loaded XAP needs to ensure that it is delivered with the correct content-type of application/x-silverlight-app to ensure that it would load properly.  We double-checked this and ensured it was (of course it was because it was already being loaded, but good to double check).  Then we couldn’t figure out why it wasn’t loading the media.

Aha!  I remembered that there was one snippet of code that was in there that does a check for a query string parameter.  In doing this, the Silverlight application uses the HTML DOM bridge to interact with, well, the HTML DOM.  This is what was causing the problem.  By default, remotely loaded XAP files cannot access the HTML DOM without the author explicitly allowing it.  So we had to add another parameter to the object tag, the enableHtmlAccess param.  I sent it to Scott in an email (after testing myself) and thought we were done.  He said it still wasn’t working.  Frustrated, we kept looking.  Sergey from the network team alerted me to a possibility of some character encoding issues.  Yep, that was it.  Here’s a screenshot from the code that wasn’t working:

Spot the issue?  The copied/pasted param quotes were not in ASCII encoding and thus I’m assuming HTML was ignoring it.  After Scott typed it out rather than pasting, it worked fine.

Phew!  Nothing like banging your head in the weeds of code when it is a little typo!

Summary

So if you are looking to host your Silverlight content on a CDN for delivery, make sure two things:

    1. The server delivering your XAP content must deliver with the correct MIME type: application/x-silverlight-app
    2. If there is any code in your XAP that does HTML bridge interaction, you’ll have to add the enableHtmlAccess param to either your object tag instantiation as a param, or to your createObject call if using Silverlight.js.

I hope this helps some!

| Comments

First a word on the “continuum” I keep hearing about for applications.  I’d like to apply it to my digital lifestyle.  You know that vision where you only have one place to keep your music, but can access it anywhere, etc., etc.  I still haven’t hit nirvana like that yet, but for movie watching it’s getting close.

I used to be a customer of Netflix when they first launched.  To be honest, at that time their pricing was singular and I just wasn’t watching enough movies at home to warrant the cost, so I ended my relationship.  Now I have kids, travel a bit, have an XBOX, etc.  For me, Netflix has become more relevant as a matter of convenience…oh and the fact they have a pricing model that totally fits in line with my use.  The thing that is great about Netflix for me now is that they “get it” with regard to how digital and old-school movie rentals can/should occur.  Why? Simple, it’s everywhere for my lifestyle now.  My Netflix account enables me to get DVDs the traditional way (even with Blu-Ray even though I don’t have a player, but nice to know the option is there) as well as digitally.  Recently they changed their Watch Instantly capabilities to use Silverlight.  But that wasn’t all.  With the launch of the XBOX next generation experience, Netflix now has an application for the XBOX.  So now I can get DVDs, watch on my computer(s) and watch on my home theater system.  All with one account, one place, etc.  The only missing piece is a supported/legal way to download to my portable media player (iPod, Zune, etc.).

The one thing that I really like about the instant watch capability is the fact that it remembers where you were.  So if I am traveling and start watching a video but couldn’t finish, when I get home to my XBOX, it starts where I left off.  Nice polish on that feature.  I can still start over if I want, but it is great to see that added value of watching where I left off.  For me, Netflix truly has figured out fast how I want to watch movies and innovates to offer the options for me.

I was showing my family these features and went to a PC in my house to show them the instant watch capabilities as an example.  It just so happened to be a machine that didn’t have Silverlight installed on it yet for some reason.  After logging in to my Netflix account and picking the first movie to demonstrate to them, I was greeted with this images:

It was a reminder of two things for me: 1) that I didn’t have Silverlight installed and 2) what paying attention to the install experience of your web application features can do to enhance the experience and loyalty of your customers.  You see in reality Netflix could have just left the default Silverlight install experience:

on a blank screen.  For me, I would have known what that meant and still been reminder.  But I’ve ranted about providing a great Silverlight deployment experience, about some easy ways of implementing it and how important it is not to assume and to optimize your rich client experiences for your users.  Netflix nails it and is the best example I’ve seen yet.  Period.  Let’s examine the key areas here (numbering mine):

Netflix focused on the main tenants of first impressions with new technology:

Maintain Visual Cues

Netflix keeps the user engaged, not by using the default Silverlight install image, but by maintaining a consistent user experience in the design.  Although the user has chosen to “watch instantly” and they are not there yet, this design helps keep a consistent brand recognition and even shows a player in the background a little bit.  This tells the user that they are still starting along the same action they desired.

Focus on the Content

Content is king.  Content is king.  Nobody will install anything if they don’t believe the content is relevant.  Look at how Netflix uses some personalization in this experience.  In section 1 you can see that they’ve alerted you about the content you chose…they haven’t forgotten about your desire.  They also put the DVD cover as a part of this experience to remind you of the content you wanted to watch.  This is HUGE to the experience.

Reduce Barriers to Entry

Some people might be apprehensive about installing new things.  In section 4 Netflix helps alleviate some concerns by showing the value of the action, and assurance that this is not something that has to do with advertising, etc.  They are providing you with additional information to help you make a decision and help you feel that the process is relative only to the task you requested (watch instantly).

Set Reasonable Expectations

In section 2, the authors of this experience help give some reasonable expectations to the user with “it only takes a minute” instructions.  This gives the user a reasonable expectation of time.  They have a reasonable assumption now that they aren’t downloading the entire movie, or something huge that will take 20 more minutes before they can watch their selected video.

Minimize Decisions

They haven’t given you any other offers here.  No option to create a new account, or sign up for other methods.  You’ve asked to watch instantly and that’s what they are presenting here…the option to do that.  They are making that decision clear in section 3 as well – this is the call to action…no other.

You may also notice the absence of giant Silverlight logos.  To me, this is a good thing.  It is important that you provide some context to your users about what they are installing if it isn’t directly from you though, whether it be from Microsoft, Adobe, wherever.  Here Netflix points out “Install Microsoft Silverlight” which puts in your mind the brand of Microsoft.  This way when the installer shows up it isn’t a surprise it isn’t from Netflix.  Perhaps adding the Silverlight brand/logo in a subtle way wouldn’t be a bad touch here to have some visual recognition and continuity from this screen to the installer.

Summary

Creating these experiences is an important step in managing first impressions.  It isn’t difficult to do either.  We provide some tools and support scripts (Silverlight.js) for you to understand the different scenarios.  Over time as more and more get Silverlight installed this will be less of an issue, but still shouldn’t be ignored.  I’ve seen many Flash sites that use the default “Get Adobe Flash” small icon and wish they would concentrate just as much on the experience as well.

I mentioned that the Silverlight.js file can help aid in detection/installation of Silverlight.  I’m curious your thoughts on it.  If you have a few minutes to spare, I’d love for you to take this very quick survey of your impressions of this technique and using the Silverlight.js script.  No personal information is required.

Bravo to the Netflix team…very well done.  Oh, and the experience isn’t that bad either ;-) -- Seriously though the player and bandwidth/quality detection is great.  Overall Netflix has won me back as a customer for sure!