Updater Block Design FlawEliminating Absolute Links
As you've seen, the block relies on absolute paths links being provided in the configuration file. But this reliance causes big problems, because you can't always guarantee that users will install your application to a specific location. Fortunately, fixing the application block is relatively simple using some basic Reflection techniques to locate the directory in which the Updater components are executing, and appending the relative link to the application name that you defined in the config file. Unfortunately, there are quite a few places where changes need to be made. Remember that the changes described in this section are purely optional, and should be undertaken only if you're determined to use relative links in the config file. If you can
ensure that all the file paths in the config file are absolute links, everything will work just fine without these modifications.
Start by changing the first line in the StartApp_Process()
method, which combines the <appFolderName>
(supposedly containing an absolute path to the folder your app is installed in) and the <appExeName>
settings defined in the AppStart config section.
_exePath = Path.Combine(
_config.FolderName , _config.ExePath );
You want to change the preceding line to use Reflection to obtain the name of the folder in which AppStart is executing, and to append the (relative) folder name and your application's executable name to it, as follows (if you remember, your app folder is a subfolder of the folder containing AppStart):
string appFolder =
_exePath = Path.Combine(appFolder +
You'll fix the Updater in a similar way. Table 3 lists the location of the changes you should make:
Table 3. The table lists the changes you must make to the Updater application to remove the Updater Block's dependency on absolute paths.
||Remove the !Path.IsPathRooted check—it will throw an
exception if you don't use an absolute link!
||Again, remove the Path.IsPathRooted check.
All these property sets are very similar, so I'll use the XmlFile
set as an example. In this property set, the _xmlFile
field is set to value
; change this as follows:
string folder = Path.GetDirectoryName(
string relativeLocation = folder + value;
_xmlFile = relativeLocation;
As you can see, this uses code similar to that used in AppStart to remove the dependency on an absolute path.
Every time the Updater downloads a new version of your application to the client, it creates a new folder to hold the new version; unfortunately, it leaves the folder(s) for the outdated version of your application and all its files intact. That's untidy, leaves open the possibility for users to run an older version, and bloats the disk space requirements for your application. Fortunately, there's a solution to thisuse a custom Updater Post Processor (note the fields for this in Figure 6
). A Post Processor runs after a download completes. To get a working example, download the source for Sam Santiago's custom Updater Post Processor
, which deletes all but the two most recent downloads, giving you a rollback path in case of problems.
The Updater block gives you the means to create self-updating Windows Forms applications today. It may not be perfect, but it does provide a glimpse of a new Microsoft distribution mechanism called ClickOnce, that will debut with Visual Studio 2005. ClickOnce will also rely on configuration and manifest files in order for it to work, but the development environment will generate these for you, so most of the headaches of using the Updater block will go away. The other headachehaving to write code to process the manifests and control the downloadwill also disappear, thanks to the System.DeploymentFramework service installed with version 2.0 of the .NET Framework. Getting to grips with the Updater Block will provide you with a thorough understanding of how .NET 2.0 and Longhorn will manage application deployment.