During the past couple of weeks, I've been doing some
of my first real dotnet WinForms App development. It's been a fun
journey, I'm still learning stuff like crazy. One of the things I
wanted to do was enable the app to be self-updating using the
ApplicationUpdater Block from MS. This took me a considerable
effort to get working right, and I thought that the MS samples lacked a
step-by-step example. Duncan Mackenzie has a good blog post here
that was a great start, but the examples were VB and it didn't go into
the specifics of the Public and Private RSA key stuff, so I thought I'd
post this walk through. I hope it works for you!
Step #1 Install the Application Blocks
Download the Updater Application Block from Microsoft .
Run the MSI Installer.
Step #2 Add the Code and References to Your Project:
Add the following projects to the solution containing your Winforms project :
Microsoft.ApplicationBlocks.ApplicationUpdater
Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces
Microsoft.ApplicationBlocks.ExceptionManagement
Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces
They should be located in the following folder, if you've accepted the defaults
C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater
Reference the following projects from within your Winforms Project
Microsoft.ApplicationBlocks.ApplicationUpdater
Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces
Microsoft.ApplicationBlocks.ExceptionManagement
Add the following namespaces to your form's .cs file.
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Xml;
Then add the application updater code located here to your code. You'll need to call InitializeAutoUpdate() from your MainForm's Initialize method.
Step #3 Create your Application's Deployment Directory Structure and Configure AppStart.exe
Create a folder for your client installation. For example purposes, we'll use the following directory:
C:\Program Files\YourApp\1.0.0.0\
Now copy the AppStart.exe and AppStart.exe.config into the root directory like so:
C:\Program Files\YourApp\AppStart.exe
C:\Program Files\YourApp\AppStart.exe.config
Note: You can find these two files in the “C:\Program
Files\Microsoft Application Blocks for
.NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\AppStart\bin\Debug“
directory.
Step #4 Modify the AppStart.exe.config File
AppStart.exe
will launch your application and allow a restart once an update has
been downloaded. It needs to know the directory to use to launch
the latest version of your app.
Modify this config file to match the current version like so:
<appStart>
<ClientApplicationInfo>
<appFolderName>C:\Program Files\YourApp\1.0.0.0</appFolderName>
<appExeName>YourAppName.exe</appExeName>
<installedVersion>1.0.0.0</installedVersion>
<lastUpdated>2004-06-10T15:33:17.3745836-04:00</lastUpdated>
</ClientApplicationInfo>
</appStart>
Step #5: Create Your Public and Private Keys
Run the ManifestUtility "C:\Program Files\Microsoft
Application Blocks for
.NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\ManifestUtility\bin\Debug\ManifestUtility.exe"
Choose “File..Generate Keys” You will be
prompted to save the following keys: PublicKey.xml and
PrivateKey.xml You'll be using these keys in the next
steps.
From what I can tell it's best to create these keys
once, because you'll need to reference these RSA public and private
keys in a couple of places. You'll want to keep your keys in
a safe place, because you'll need them when pushing new
updates.
Step #6 Create Your IIS Virtual Directory
Create a directory on your WebServer to house your updates. You will end up with two things in this directory 1) a ServerManifest.xml
file which will contain the latest version information, and 2) your new
application directory. Within this directory, create a directory to
house your new application version. So, for our example, we'll
create the directories, C:\Inetpub\AppUpdates and C:\Inetpub\AppUpdates\1.0.0.1
Use IIS Manager to create a virtual directory
pointing to this physical directory. Remember your URL, as you
will need it in an upcoming step. You will have to enable
directory browsing for this virtual directory.
Step #7. Configure Your Version 1.0.0.0 App.config File
Here, we'll need to add a few things. First, we need to add a configSections element to define our appUpdater section:
<configSections>
<section name="appUpdater" type="Microsoft.ApplicationBlocks.ApplicationUpdater.UpdaterSectionHandler,Microsoft.ApplicationBlocks.ApplicationUpdater" />
</configSections>
Next we need to add the Version key to our
appsettings key, we're first going to set our local versoin to 1.0.0.0,
so that we can test the auto-update to version 1.0.0.1
<appSettings>
<add key="VERSION" value="1.0.0.0" />
</appSettings>
Finally, add the appUpdater section to your
config file. I've put brackets where you need to edit the
values. You can just copy the <RSAKeyValue> element from
the PublicKey.xml file that you created in the previous step.
The <xmlFile> elements should point to your Virtual directory's URL that you created in step #6.
<appUpdater>
<UpdaterConfiguration>
<polling type="Seconds" value="120" />
<logListener logPath="C:\Program Files\YourApp\UpdaterLog.txt" />
<downloader type="Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader"
assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/>
<validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">
<key>
<RSAKeyValue>
<Modulus>[YOUR MODULUS KEY]</Modulus>
<Exponent>[YOUR EXPONENET]</Exponent>
</RSAKeyValue>
</key>
</validator>
<application name="[YOUR APP NAME]" useValidation="true">
<client>
<baseDir>C:\Program Files\YourApp</baseDir>
<xmlFile>C:\Program Files\YourApp\AppStart.exe.config</xmlFile>
<tempDir>C:\Program Files\YourApp\temp</tempDir>
</client>
<server>
<xmlFile>http://[YOUR URL]/ServerManifest.xml</xmlFile>
<xmlFileDest>C:\Program Files\YourApp\ServerManifest.xml</xmlFileDest>
<maxWaitXmlFile>60000</maxWaitXmlFile>
</server>
</application>
</UpdaterConfiguration>
</appUpdater>
Step #8 Deploy Version 1.0.0.0
Version your app. You do this by setting the version attribute of your app's AssemblyInfo.cs file.
[assembly: AssemblyVersion("1.0.0.0")]
Build the Application and copy version 1.0.0.0 to your program file's 1.0.0.0 directory. “C:\Program Files\YourApp\1.0.0.0“
At this point, you should be able to run
AppStart.exe. The update process should fail, since we haven't
deployed the ServerManifest XML file which tells our app that there's a
new version available. You can inspect the log files that should
be created in your C:\Program Files\YourApp\ directory.
Step #9 Buld Version 1.0.0.1
This is the fun part. First, create revision
1.0.0.1 by updating your application's AssemblyInfo.cs and App.config
files to reflect the new version. Build your application, and
copy the files to the web server directory created in step #6.
Step #10 Create Your Server Manifest File
This should be the last step. Any changes you
make to the .config files from this point on will require repeating
this step. To do this:
- Launch the ManifestUtility program again.
- Choose the 1.0.0.1 directory from the “Update files folder“ chooser.
- Enter the URL of the update location.
- Enter version 1.0.0.1
- Open your PrivateKey.xml file created earlier.
- Choose the validator class “Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator”
- Click CreateManifest, and save the ServerManifest.xml file to your virtual server directory.
That's it! Pheeew! Run your AppStart.exe from your C:\Program Files\YourApp\
directory. Your app should launch, and you should now be
prompted that “A new version is available” when you launch your
application. The new app should be downloaded into your C:\Program Files\YourApp\1.0.0.1
directory, and the app should re-start itself. If you have
problems, be sure to check the log files that are created during the
process. They can be very helpful in tracking down bugs.
-Brendan
Posted
06-10-2004 11:25 AM
by
Brendan Tompkins