Top 5 Secrets of .Net Desktop Deployment Wizards

Deployment is one of the software project taxes that are often neglected or shunted aside to have another team deal with.

There are two big downsides when a team does not directly own it's deployment. The first is obvious, if the quality of the deployment infrastructure isn't any good, users perception of your software will suffer. Rightfully so, any you find yourself spending time fixing bugs that are only tangential to your project.

The second risk has to do with how outsourcing (to another group, another department or other company) deployment infrastructure can affect your project.  If the amount of time it takes to get a new deployment ready is more than an hour - you'll find yourself adjusting the release schedule to accommodate this - typically in the direction of longer delays between releases.  No need to rehash the downside of that.

Here are some tips to taking control of deployment.

Secret #1

To install to the desktop, use ClickOnce.

You no longer need to be dependent on the installation and packaging department.

The core ClickOnce technology continues to improve from its inception in .Net 2.0 - In .Net 3.5 SP1 ClickOnce has support for the reduced client profile, FireFox installs, and file type registration.

 

For enterprise environments there are a few things that you'll need/want to do to make ClickOnce really work for you

The most important thing is having support for multiple environments - this isn't built in, and if you attempt to deploy two different ClickOnce builds with the same deployment name to different sites, the latest build will take precedence and effectively overwrite the existing deployment on the desktop.

The fix for this is relatively straightforward - you need to provide different deployment name for each build. Like so -

<MSBuild 
   Projects="ClickOnce.csproj"
   Targets="Publish"
   Properties="
            MinimumRequiredVersion=$(MinimumRequiredVersion);
            ApplicationVersion=$(ApplicationVersion);
            ApplicationRevision=$(ApplicationRevision);
            CodeBranch=$(CodeBranch);
            DeployEnv=$(DeployEnv)
            AssemblyName=ClickOnce.$(DeployEnv);
            PublishUrl=$(PublishUrl);
            ProductName=ClickOnce $(CodeBranch) $(DeployEnv)" />

The one limitation of this approach is that project references will no longer work. Use file based assembly refs, and it'll be fine.

For a more polished look obtain a code signing certificate. Instead of getting an install dialog that says "Unknown publisher", you can indicate the name of your group. It also make the auditors feel warm and fuzzy.

And finally, you can make your desktop software URL addressable. Even though most workflow software in the enterprise has moved to the web, the need for desktops software still exists, and often this desktop software can benefit by supporting URLs.  And rather than telling your colleague how to navigate to what you're looking at, or sending a screen shot of what you're looking at, you could send them a URL - which would open up to the screen you're using.

If you were installing the software via windows installer you could rely on modifying the registry and register a protocol handler.  That approach won't work for non-administrator ClickOnce installs, but you can work around that limitation by enabling "URL parameters to be passed to the application" (thanks to my co-worker Eugene for discovering this one)

Update - Cedric in the comments wonders if ClickOnce limits the application to a ".Net Sandbox?" In many ways, not really. In full trust mode, ClickOnce applications can run unmanaged code via pinvoke and Reg-Free COM. For applications that truly need unmanaged component installs you can use the setup bootstrapper, or if you are in an enterprise situation, install the core components separately from the application.

Secret #2

To get the server components and ClickOnce files to the deployment site, use WiX to prepare a Windows Installer packages.

Sure, you could use Visual Studio Setup Projects, or even shell out some real money for InstallShield or Wise software. But WiX has a number of nice features

  1. cost
  2. text (well xml) based files so you can do the decent diffs and source control on them
  3. active community support
  4. reasonable learning curve - start with everyone's favorite WiX tutorial

Secret #3

Get your configuration files under control

Secret #4

Although WiX is great, sometimes installs just too difficult to be done in Windows Installer technology. In this case, use PowerShell.

If the install involves modifying xml files, executing database commands, or invoking web services and it's well outside the normal range for windows installer. Read than trying to force everything into one technology, simply distribute a PowerShell setup scripts in the installer package. Run them from the msi or by hand afterwards.

Secret #5

Working on deployment can help your career.

It's true.  Responsibility and influence on a project naturally flow to those that get things done (not sure if it matter that you're smart or not). Few things are a more visible indication getting things done then a release, and if you own deployment, other project items will naturally flow your way.

kick it on DotNetKicks.com

3 Comments

  • If your application requires SQL Server MSDE or some other legacy COM component or access to some un-managed code that must be installed via child MSI or regsvr32.exe....

    Can you still use ClickOnce?

    Should you caveat this article with... "ClickOnce is great if you stay in the .NET Sandbox."?

  • Secret #1: I tried looking ud refrences for the Names on the MSBuild Properties you are using (DeployEnv, CodeBranch, and AssemblyName); were did you find refrence for these, and other MSBuild Properties?

  • Stewart - DeployEnv, CodeBranch are custom properties. The idea is for the build system to set them for the specific builds you need.

    AssemblyName is part of the msbuild common targets file, found in the .Net FW directory.

Comments have been disabled for this content.