WPF is all about creating great user experiences, but the user experience of your application starts long before your code starts running on the end user’s machine. An important first step is launching your application and getting your code down onto the end user’s machine as quickly and simply as possible. ClickOnce makes great strides in improving this deployment experience for .NET 2 rich client applications and WPF applications, however the default publish page that is generated by visual studio can be greatly improved. In this article we discuss techniques to reduce the amount of decision-making required of the end user, and give them an experience tailored to their operating system version, browser version and system capabilities to minimize the size of the download for clients on sub-broadband network connections.
The broad approach we’ll be trying to take is:
- Identify potential users who can have WPF installed and can start using our application right away.
- Create a hyperlink to launch our application that works for their browser.
- For those users who need to install .NET Framework 3.0 direct them to do so and then give them a link to launch our application.
- For those users who we believe will not be able to run any WPF applications, give them the option of trying to install .NET Framework 3.0 and our application, but warn them that it may not work and why.
Identifying WPF-capable clients via the User Agent String
The user agent string is an optional parameter that can be sent as part of the HTTP headers when making a request to a web server. The user agent string is intended as a means for the client to identify itself to the server, so the server can optionally adjust the response if appropriate. Although the content of the user agent string is entirely free form and does not carry any guarantees regarding accuracy or authenticity, it is still broadly useful for identifying browser versions and client capabilities.
Identifying WPF-capable Clients using Internet Explorer
By default Internet Explorer includes the versions of the .NET framework present on the client in the user agent string like so:
Example Microsoft Internet Explorer 7.0 User Agent String on Windows Vista:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)
(an exhaustive list of User Agent strings can be found here)
Fortunately the System.Web namespace contains the helpful HttpCapabilitiesBase class which can perform the task of parsing out the available CLR versions on the client. The code below assumes that WPF will be included in versions of .net framework subsequent to version 3.
HttpCapabilitiesBase httpCapabilities = HttpCapabilitiesBase.GetConfigCapabilities("system.web/browserCaps", HttpContext.Current.Request);
Version wpfV1FinalVersion = new Version("3.0.04506");
Version clrVersions = httpCapabilities.GetClrVersions();
foreach (Version clrVersion in clrVersions)
if (clrVersion >= wpfV1FinalVersion)
// client has WPF
For clients that have WPF installed we can simply link directly thru to the .application file generated by ClickOnce, which will prompt the user to install our application. For clients that don’t have the .NET Framework 3.0 or better installed we can direct them to where it can be downloaded, and then prompt them to launch our application. Alternatively we could launch the ClickOnce bootstrap setup.exe which can install pre-requisites on the client’s machine.
Identifying WPF-capable Clients using Mozilla Firefox
Unlike Internet Explorer, Mozilla does not include the .NET CLR versions installed on the client computer as part of the user agent string. However since Windows Vista comes with WPF pre-installed on it we can check the Mozilla user agent string for the Windows version, and for Vista users assume they have WPF. For Windows XP and Server 2003 users we can indicate that WPF is supported, that we can’t tell if they have it or not and provide them with a two-step installation process (step 1 being to install .NET Framework 3.0, and step 2 to install our application).
Example Mozilla Firefox 2.0 User Agent String on Windows Vista
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:188.8.131.52) Gecko/20070219 Firefox/184.108.40.206
For users that don’t appear to be using Windows, or who are using an older version of windows we revert to our fallback position – tell them that we believe they won’t be able to run our application but they are welcome to try with the two steps listed above.
Serving the Right Files to Launch our Application in Mozilla Firefox
Unfortunately identifying WPF-capable clients using Firefox is only the beginning, because the .application file used to launch your ClickOnce application does not work in Firefox (although there are some add-ins for Firefox that allow them to work). Cross-browser support was de-scoped from ClickOnce between Beta 2 and RTM, but luckily there is a work-around where Mozilla users running windows can be served a .appref-ms file. A .appref-ms is a kind of ClickOnce version of a desktop shortcut, which will then correctly launch your application for them (if they have .NET Framework 3.0 installed). The easiest way to get your hands on one of these files for your application is to deploy it using IE and ClickOnce, and then copy the shortcut that is created in the start menu – that is a .appref-ms file. You will need to deploy this file yourself. If your application is being served up by IIS you may need to add a MIME type mapping for .appref-ms files also.
Why not just direct users to the ClickOnce bootstrap setup.exe program?
The ClickOnce bootstrap executable (setup.exe) is a useful way to launch your application installation in some cases, however there are some issues with it. Setup.exe doesn’t work with Mozilla Firefox if it is the default web browser on the client system. Also Firefox users on Vista see a moderately concerning prompt about running executables downloaded from the internet. For users who already have the pre-requisites necessary to run your application on slower network connections the 400K download of setup.exe is time and bandwidth wasted. For users on XP SP2 running IE who do not have .NET 3.0 installed setup.exe is a good choice.
A sample user control and code for detecting clients with WPF installed can be downloaded from here.