CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

Create a Self-Updating WinForms App with the Application Updater Block

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:

  1. Launch the ManifestUtility program again. 
  2. Choose the 1.0.0.1 directory from the “Update files folder“ chooser. 
  3. Enter the URL of the update location. 
  4. Enter version 1.0.0.1
  5. Open your PrivateKey.xml file created earlier.
  6. Choose the validator class “Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator”
  7. 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



Comments

Mark Bonafe said:

Great post!
# June 11, 2004 1:37 AM

Brendan Tompkins said:

Thanks Mark! You playing cricket tomorrow?
# June 11, 2004 2:00 AM

Darrell said:

Yes Brendan, excellent post. Have you written any stored procs lately? :)
# June 11, 2004 2:06 AM

David Hayden said:

This is really great. Very generous of you to share your hard work! Keep us posted on your adventure!

Out of curiosity, are there any tools, components, or resources you would recommend for people starting winforms development? Thanks again!
# June 11, 2004 4:21 AM

Brendan Tompkins said:

Hi David... I've got Chris Sells book on C# Winforms

http://www.sellsbrothers.com/writing/wfbook

... but I haven't read it yet. Look into the "Genghis" project too, that was a big help for doing things like taskbar notification popups...

http://www.sellsbrothers.com/tools/genghis/



# June 11, 2004 4:31 AM

David Hayden said:

Thanks, Brendan! I just purchased Chris Sells' book today from Amazon along with a couple others. It has great reviews, so I can't wait to get it. Thanks for the recommendation.



# June 15, 2004 2:02 PM

hula said:

I searched from east to west on google! and finally got you!

I like step by step guides!

thanks
# June 17, 2004 4:14 PM

hula said:

Hi,

After having used the updater block and sucessfully deployed the app+crystal reports to the client machine app ver 1.0, now i have updated the crystal report file with changes how do i deploy the updated report only to the existing app on the client machine app ver 1.0, wihout creating a new version for the app.

Is it possible for the updater block to check for the changes in file modified date for the report and copy the files or is there any other way to do it

Thanks
# June 20, 2004 3:31 PM

Brandon said:

Almost Works still doesn't quite want to load.

Get an Error in the exe.config wondering what the VIT in your path is
# August 11, 2004 10:25 AM

Brendan Tompkins said:

Ooops! Er. You'll want to remove that. Updated article. Thanks!
# August 11, 2004 10:30 AM

Brandon said:

Was wondering if how to close the app though I believe the thread is still running. Can I simply call the StopUpdater() method?
# August 11, 2004 11:31 AM

Brandon said:

yeah I just added the StopUpdater() to the form_closing event

I love this thing so much thank you. Have you overloaded any of the classes yet. Like to report back to the gui download progress, and where in the process it is kinda like windows update .?
# August 11, 2004 11:43 AM

Brandon said:

Check out this link, I don't know why I need to make anything anymore
# August 12, 2004 7:16 AM

Rick Stephens said:

AUB is great, but I've run into a few problems. I've noticed that all of the config files require absolute paths. When dealing with commercial applications, we allow the installation to take place anywhere, thus requiring us to make changes to app.config at installation. Wise doesn't have a great interface for working with xml files, so I've had to create a little "Run Once" program that modifies the app.config files when the application is run for the first time. Is there a better way to handle this?
# August 15, 2004 2:15 PM

Brendan Tompkins said:

Not that I'm aware of. I've heard this mentioned before in the groups. Maybe in the next version?
# August 16, 2004 2:28 AM

Mario Karagiorgas said:

Hi,
Thanks so much for the work.
Do you need to install BITS 1.5 client components separately for this app block and is that the right version for win serv 2000 if you don't want to go to 2.0?
# August 24, 2004 1:01 PM

Sudhir Shetty said:

Great step by step guide, it went off till the last but got stuck here. any idea :( wat i did wrong

[ClientApplicationInfo.Deserialize] :
Could not deserialize an instance of ClientApplicationInfo:
error message was 'Object reference not set to an instance of an object.'.
The path to the Server Manifest was 'D:\Test\1.0.0.0\Idealaker.exe.config'.
ERROR: Object reference not set to an instance of an object.
STACK: at Microsoft.ApplicationBlocks.ApplicationUpdater.ClientApplicationInfo.Deserialize(String filePath)
# September 2, 2004 12:32 AM

John Gummel said:

What changes to the App.config file would be necessary for the update to occur before the application starts, as opposed to a polling method: <polling type="Seconds" value="120" />.
Thanks.
# September 7, 2004 11:48 AM

Robert Socolich said:

Good article that helped out a lot getting this incorporated into my app. I followed the instructins but when I launch my app (via Appstart.exe) the download fails. The error message is:

[BITSDownloader] :
The BITS service returned an error for the job with the ID 'a7ab5100-b281-4214-b163-d3d43e03187f';
the job's name and description are 'BITS_Files_Download_Job' and 'BITS_Files_Download_Job'.
The BITS service error message for this job is
'The server has not found anything matching the requested URI (Uniform Resource Identifier).

'.
This job has been canceled, and the DownloaderManager will attempt it again. If you see this error frequently, you may have a mis-configuration, or another
administrator process/user is canceling BITS jobs.
It is also possible that some mis-configuration of the Manifest file is causing BITS to have trouble with a source or destination path;
be sure that all SOURCE paths are valid URLs, and that all DESTINATION paths are valid LOCAL UNC paths--__shares are not allowed__.

Any ideas what the problem is.
# October 1, 2004 1:05 PM

Rich said:

Thanks for the excellent walkthrough of how to get this working...

I'm getting the same error as Robert Socolich - has anyone worked out what causes this??

# November 3, 2004 11:15 AM

Rich said:

Sorry - cancel that last post - I realised that I had forgotten to append the version number to the update URL, so the downloader was trying to download from the wrong location (Duh...).

I have now managed to get it downloading fine, but for some reason the appstart program doesn't start the new version (it doesn't appear to have updated the appstart.exe.config file with the new version number).

Any ideas on this one??
# November 3, 2004 2:34 PM

David said:

Thanks for this clear step-by-step article. I have been struggling with this for the better part of a day now and am now feeling much more optimistic!

I do still get an error on loading - which I can only think is related to the fact that all my assys are strong-named. I have also had to recompile the AppUpdater dlls with strong names.

The error I get is (from the log):

[GenericFactory.Create] :
The assembly and type specified could not be loaded.
The assembly name given is 'Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=21 62 2C EB 0C CA FD 9F'
and the type name given is 'Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader'.
Check to be SURE that the FULLY QUALIFIED ASSEMBLY NAME with assembly, version, culture, and PublicKeyToken is specified. Check
also that the type name is the FULL type name not the abbreviated type. It is common to have incorrect versions or PublicKeyTokens,
validate these and correct the config. Likewise, the TYPE that must be constructed must be specified by the FULL TYPE NAME,
not just the class name. Type names are NOT necessarily just the "assembly.type" form;
type names depend on namespace, which may or may not be the same as the assembly name.


Any help greatly appreciated. Thanks again for the article.

David
# November 11, 2004 12:14 PM

Hugo Castillo said:

Hi:

The post is excellent. But i have a problem, i follow the instructions and the application run Ok in mi PC, but when i tried deploy the app in another PC, i get the following error.

Some body have an idea?

Thanks, and sorry for the english, im not american.
The BITS service returned an error for the job with the ID 'ff8aec94-4464-4181-b479-d79ee3e2b81e';
the job's name and description are 'Updater job.' and 'Updater: Download the Server XML File.'.
The BITS service error message for this job is
'The requested resource requires user authentication.
# November 24, 2004 4:56 AM

Olivier Vaillancourt said:

About the strong name thing giving problems.

We found that you need to update the publicKeyToken property in the app.config file of your project. It is set to null by default because the assemblies are not signed.

Hope it helps.
Olivier
# December 7, 2004 6:44 AM

Peter said:

I followed all the step and I keep getting this error. Any comments?

[ApplicationUpdateManager.StartUpdater] :
The Updater has started; the target application's name is 'MyApp'. Time started: 2005_01_20_10:04:12.

[DownloaderManager.RunDownloader] :
Checking on updates for application 'MyApp'.


[DownloaderManager.IsServerManifestDownloaded] :
DOWNLOAD STARTED: Downloading manifest for the application 'MyApp'. Time started: 2005_01_20_10:04:12


[DownloaderManager.IsServerManifestDownloaded] :
SOURCE FILE: 'http://server.com/updates/MyApp/ServerManifest.xml'


[DownloaderManager.IsServerManifestDownloaded] :
DEST FILE: '\AppManifest.xml'


[DownloaderManager.IsServerManifestDownloaded] :
The metadata file (the Server Manifest) can't be downloaded for the application 'MyApp'.
Either the manifest is unavailable (check download URL in Updater config file), the downloader failed, or
the Manifest failed validation.
ERROR: Exception from HRESULT: 0x8020000F.
STACK: at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.IBackgroundCopyJob.GetError(IBackgroundCopyError& ppError)
at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader.HandleDownloadErrorCancelJob(IBackgroundCopyJob copyJob, String& errMessage)
at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader.Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces.IDownloader.Download(String sourceFile, String destFile, TimeSpan maxTimeWait)
at Microsoft.ApplicationBlocks.ApplicationUpdater.DownloaderManager.IsServerManifestDownloaded()
# January 20, 2005 5:31 AM

Brendan Tompkins said:

Peter,

Are you using Windows 2000 with a Terminal Services login? If so, the BITS downloader won't work. Try logging in with an interactive session.

Brendan
# February 5, 2005 8:38 AM

Muhammad said:

Peter,

In your app.config make sure to put the complete path like "<xmlFileDest>C:\AppUpdaterTest\ServerManifest.xml</xmlFileDest>" instead of <xmlFileDest>\AppManifest.xml</xmlFileDest>.

I have been able to download the new version but I am stuck on start the new version. Every time I run AppStart it is still starting previous version. Any body has any clue???
# February 8, 2005 1:56 PM

Muhammad said:

Finally, I found the problem with starting the new version. Actually, the code below defined in the InitializeAutoUpdate() method is misleading.


// get version from config, set caption correctly
string version = System.Configuration.ConfigurationSettings.AppSettings["version"];
this.Text = this.Text + String.Format(" v. {0}", version);

What I found was that everytime I ran the application I was getting the new version and AppStart was starting the new version. But this code always shows the verison as 1.0.0.0.

I changed it to :

textBox1.Text = Application.ExecutablePath + " : " + Application.ProductVersion;

This way you can see the actual assembly product version.
# February 9, 2005 7:41 AM

Param said:


[DownloaderManager.RunDownloader] :
The metadata file (the Server Manifest) can't be downloaded for the application '.
Either the manifest is unavailable (check download URL in Updater config file), the downloader failed, or
the Manifest failed validation.
ERROR: UNCDownloader.Download: Error copying files
STACK: at <applicationNamespace>.Downloaders.myDownloader.Download(String sourceFile, String destFile, TimeSpan maxTimeWait)
at Microsoft.ApplicationBlocks.ApplicationUpdater.DownloaderManager.IsServerManifestDownloaded()
ERROR: UNCDownloader.Download: TIMEOUT ERROR
STACK: at <applicationNamespace>.Downloaders.myDownloader.Download(String sourceFile, String destFile, TimeSpan maxTimeWait)

# February 10, 2005 4:55 AM

Brendan Tompkins said:

Make sure you're not using a Terminal Services Login under W2K. BITS doesn't work in this scenario.
# February 10, 2005 6:10 AM

Jasim said:

Hi All,

Great post solved many of my initial problems. But now I'm just stumped !!!

Is it possible that I could download files which have GreaterTimeStamp than the files present in the application directory. So instead of downloading the whole app again, only updated files are downloaded in the same folder as the application(but files which I want to download are NOT IN USE by APP).

My Scenerio is as follows:

In my app only the documents folder will be changed, and out of those 32 files, only few(3-4) files will be changed. So it does not make sense to download the whole documents again, overwritting them.

Does anyone have any suggestions?

-jasim
# February 14, 2005 11:40 AM

TrackBack said:

# March 3, 2005 4:53 PM

belle said:

hi! thanks for the nice post, really helpful..just got confused in ..

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.

- does this mean i may now modify my code? and then change all "1.0.0.0" to "1.0.0.1" in both my AssemblyInfo.cs and App.config files? or are there other changes to both files that i must do?
-what files am i going to copy in my web server? the installer of my application (.exe file) ?

just need to clarify co'z my application does not recognize the new version, i just gives me the option of either repairing or removing my application when i run AppStart.exe from my C:\Program Files\YourApp\ .

thanks! =)
# March 15, 2005 7:36 PM

Brendan Tompkins said:

- does this mean i may now modify my code? and then change all &quot;1.0.0.0&quot; to &quot;1.0.0.1&quot; in both my AssemblyInfo.cs and App.config files? or are there other changes to both files that i must do?

All you should have to do is modify the AssemblyInfo.cs to your new version


-what files am i going to copy in my web server? the installer of my application (.exe file) ?

No! You you just put the .exe and .dll files "raw" on the server.
# March 16, 2005 6:02 AM

Brett said:

I've got the following error likely due to some dumb typo. Can someone give me a pointer?

System.Configuration.ConfigurationException: The 'UpdaterConfiguration' start tag on line '19' doesn't match the end tag of 'downloader' in file 'file:///C:/MemberMatic/1.0.0.0/MemberMatic.exe.config'. Line 41, position 3. (C:\MemberMatic\1.0.0.0\MemberMatic.exe.config line 41) ---> System.Xml.XmlException: The 'UpdaterConfiguration' start tag on line '19' doesn't match the end tag of 'downloader' in file 'file:///C:/MemberMatic/1.0.0.0/MemberMatic.exe.config'. Line 41, position 3.
# June 23, 2005 12:51 PM

Martin Staael said:

You have to add

#endregion to the application updater code

also you have to add:

using Microsoft.ApplicationBlocks.ApplicationUpdater;

To get the code working.

Martin
# July 25, 2005 1:21 AM

AdoSun said:

The link to the code to add in my application is not available anymore :(.
# August 17, 2005 8:29 AM

Anwar said:

I need to implement the self-updating thing in my application and hence came to this article thru google. I appreciate very much the time and efforts Brendan has put in for coming up with such a step-by-step approach oriented article. But I find the code to be added to the application is missing (http://www.intrinsigo.com/bsblog/AppUpdater.txt), which is a sad part. Can any one of you guys post the code of the link on to this page who have already implemented this thing in their application and have succeeded. Would be a great help !!
Cheers !
# August 18, 2005 3:43 AM

Brendan Tompkins said:

Sorry. It's fixed now.
# August 18, 2005 4:04 PM

Anwar said:

Thanks Brendan, nice of you to fix the code link. The initial part is working perfect where the user is prompted to download the new version. But, I am getting some problem where the log file mentions that the client does not have sufficient access rights to the requested server object and the code is not download but the temp directory is created. I guess this problem is with the IIS setting for the virtual directory and/or accessiblity of the client to it. The server and client are on single machine.

Please do help and reply to what could be the problem or what areas I can re-check.

Thanks in advance !
Take care.


Error in log file:
-------------------
[BITSDownloader] :
The BITS service returned an error for the job with the ID 'b107feed-4906-4843-830c-fcbfdba69bd4'; the job's name and description are 'BITS_Files_Download_Job' and 'BITS_Files_Download_Job'. The BITS service error message for this job is 'The client does not have sufficient access rights to the requested server object.
# August 20, 2005 2:06 AM

Anwar said:

Brendan,
As the server and the client were on the same machine, I think some assemblies or other files in server's new version directory (1.0.0.1) were "in-use" or getting referred somewhere in my machine. So these files were not accessible to client for download and hence giving error I mentined in my earlier comments, though the client was able to download the Manifest.xml from server and read its contents. But, when I kept a single dummy zip file in the server's new version directory and creating the Manifest.xml over it, it did work fine as expected. Ofcourse the re-loading of application won't work with zip file. I think, as a matter or practice, we should always keep the server and client as seperate machines. Anyways, sorry taking your time, but your article did help solving my major problems. Lets hope it works well for me in actual implementation.
Cheers !
# August 21, 2005 3:44 AM

Atilla said:

Great post!

The project works well on my Server with IIS. I mean, if the server and the client are the same machines.
But if try to update my app on a second client, I just get always the same error (see attached log-content!):

[ApplicationUpdateManager.StartUpdater] :
The Updater has started; the target application's name is 'APP_Update_Test.exe'. Time started: 2005_10_03_15:11:58.

[DownloaderManager.RunDownloader] :
Checking on updates for application 'APP_Update_Test.exe'.


[DownloaderManager.IsServerManifestDownloaded] :
DOWNLOAD STARTED: Downloading manifest for the application 'APP_Update_Test.exe'. Time started: 2005_10_03_15:11:58


[DownloaderManager.IsServerManifestDownloaded] :
SOURCE FILE: 'http://pc322/AppUpdates/ServerManifest.xml'


[DownloaderManager.IsServerManifestDownloaded] :
DEST FILE: 'C:\Program Files\MyAPP\ServerManifest.xml'


[DownloaderManager.IsServerManifestDownloaded] :
The metadata file (the Server Manifest) can't be downloaded for the application 'APP_Update_Test.exe'.
Either the manifest is unavailable (check download URL in Updater config file), the downloader failed, or
the Manifest failed validation.
ERROR: Die angegebene Sprachenkennung für die Ressourcen wurde nicht in der Image-Datei gefunden.
STACK: at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.IBackgroundCopyError.GetErrorDescription(UInt32 LanguageId, String& pErrorDescription)
at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader.HandleDownloadErrorCancelJob(IBackgroundCopyJob copyJob, String& errMessage)
at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader.Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces.IDownloader.Download(String sourceFile, String destFile, TimeSpan maxTimeWait)
at Microsoft.ApplicationBlocks.ApplicationUpdater.DownloaderManager.IsServerManifestDownloaded()


I have tested my IIS with the second workstation. I am able to browse in the directory structure of the server and I can also download files. I don't use a Terminal Service Login....

Who can help?

regards
# October 3, 2005 9:19 AM

Deepak Bal said:

Great post.
Helped me to understand the working of UAB in a couple of hours.

Thanks and I really appreciate it.

Deepak
# October 19, 2005 5:40 PM

Eyal said:

Great Post!!! Helped me a lot!

Have one problem ...

When I use useValidation="false" in the appUpdater config file, the update is applied well but I have to restart the app manually.

When I modify the useValidation=true, the app.exe.config file does not pass the validation for some unknown reason, causing the Temp folder to be deleted and no updates to be applied. Other files including the manifest are validated well.
The error looks like that:

[DownloaderManager.ValidateFiles] :
FILE VALIDATION FAILED:
The file 'SelfUpdaterApp.exe.config' failed validation.
Stopping validation, deleting all files to prevent questionable files from remaining.


Any ideas...

Thanks in advance!
# December 7, 2005 9:29 AM

Amish said:

I am using .Net App Updater Block 1.0 .I need to poll server to check for updates every 3 minutes .so i specified "<polling type="Minutes" value="3" />".
Now when i run my application ,instead of checking for updates every 3 minutes , the Updater block checks for updates after the application is loaded.

Can you please tell me where am i going wrong ? Do we need to set any additional properties for the same ?

Or Is it that i have to write special code to make the the Updater thread sleep for 3 minutes ? If yes then what is the significance of <polling> element ?
# January 24, 2006 1:28 AM

Adam said:

I was wondering if anyone knew about the ResumeUpdates() functionality, from what i can see the UAB looks for any manifests that have not been applied successfully and redownloads the files. However if the majority of the files had been downloaded and then errored, the next time the app is run UAB notices the error, but downloads all the files again.

Is there any way to check the registry to determine which files have downloaded successfully and which have not.
# February 8, 2006 9:57 AM

Haris said:

How to get the errors on the main form that are occuring int updater classes, i have tried using try catch blocks but I cant get them. Any suggestion by Brendan Tompkins?
# April 29, 2006 6:46 AM

Balu.B.Chand said:

Good post!
I had set Validtion to false. Is that the problem that my app has to be restarted manualy every time when new update comes...

Please help me!!!

Thanks in advance
# May 4, 2006 2:17 AM

Brendan Tompkins said:

Unfortounately, I haven't looked at this stuff since I wrote this post. This technology is very finicky.. If at all possible, I'd use the new ClickOnce stuff.  Good luck guys!
# May 4, 2006 8:49 AM

Jeremy said:

This is a ridiculous overkill for something that is actually much easier to do yourself. I spent about 2hrs unsuccessfully getting this one to work, and another hour writing my own one from scratch, which is so much easier to understand and use. Key elements: 1. Compare own version from (assemblyinfo.vb) with that return from a webservice. 2. Prompt user for upgrade. 3. Request the set of dlls from the webservice (array of simple class with file name and byte array. 4. Save these to temp folder. 5. Call to a seperate executable (updater.exe) and exit application. 6. Updater.exe overwrites the dlls with the new ones, and then calls the exe. 7. Subsequent call to webservice finds that version is the same, so app loads normally. Piece of cake, only one extra project and a total of about 3 pages of code.
# August 5, 2006 4:00 AM

Rakesh said:

Hi Jeremy,

Please send me the full code with the steps.

# August 29, 2006 12:25 AM

Jeremy said:

What part did you have trouble with Rakesh? I am happy to put the code in the public domain if you can make it easy for me (so others can benefit), otherwise if its just for you then I am very happy to provide a commercial consulting service. Also, your post did not include any contact details.

# August 31, 2006 9:03 AM

surender singh said:

It is giving me the problem " MANIFEST VALIDATION FAILED:  "

My log file is

[ApplicationUpdateManager.StartUpdater] :

   The Updater has started; the target application's name is 'MicrosoftUpdaterBlock'.  Time started:  2006_09_01_17:51:51.

[DownloaderManager.RunDownloader] :

   Checking on updates for application 'MicrosoftUpdaterBlock'.

[DownloaderManager.IsServerManifestDownloaded] :

     DOWNLOAD STARTED:   Downloading manifest for the application 'MicrosoftUpdaterBlock'.  Time started: 2006_09_01_17:51:51

[DownloaderManager.IsServerManifestDownloaded] :

     SOURCE FILE:  'http://localhost/AppUpdates/ServerManifest.xml'  

[DownloaderManager.IsServerManifestDownloaded] :

     DEST FILE:  'C:\inetpub\AppUpdates\ServerManifest.xml'  

[ServerApplicationInfo.Deserialize] :

   Reading Server Manifest file from 'C:\inetpub\AppUpdates\ServerManifest.xml' to deserialize into a ServerApplicationInfo object.

[DownloaderManager.IsServerManifestDownloaded] :

   Server Manifest successfully downloaded to location 'C:\inetpub\AppUpdates\ServerManifest.xml'.

[DownloaderManager.ValidateManifestFile] :

   Validating the downloaded server Manifest file located at:

'C:\inetpub\AppUpdates\ServerManifest.xml'.

[DownloaderManager.ValidateManifestFile] :

     MANIFEST VALIDATION FAILED:  

The server Manifest located at

'C:\inetpub\AppUpdates\ServerManifest.xml' failed validation.  

It is being deleted; its signature did not match the signature of the file that was downloaded.

# September 1, 2006 7:24 AM

Ana said:

Great article. Very helpful.

What changes are necessary for the update to occur before the application starts?

# September 4, 2006 6:42 AM

Nicholas said:

Sorry for posting so late but Love the tutorial. It helped me alot. Well anyways my question is is there anyway to allow this updater work not an IIS server? Ive searched plenty of places and have had no luck. I had seen one before but cant find it anymore.....

Thanks

# March 21, 2007 7:56 PM

Abhijit said:

Hi:

The post is excellent. But i have a problem, i follow the instructions and the application run Ok in mi PC, but when i tried deploy the app in another PC, i get the following error.

Some body have an idea?

The BITS service returned an error for the job with the ID '892b971f-4544-4fae-835a-2a34cd5e5ea7'; the job's name and description are 'BITS_Files_Download_Job'.  

The BITS service error message for this job is

'The requested resource requires user authentication

# July 13, 2007 2:07 AM

Jerry said:

this is a great article, very helpful.  however, i'm getting the following error trying to get it to run:

[DownloaderFactory.Create] :

   Error initializing Downloader provider:

type: 'Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader',

assembly: 'Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null'.

   ERROR: Object reference not set to an instance of an object.

STACK:   at Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader.Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces.IDownloader.Init(XmlNode config) in C:\Documents and Settings\JRoxas\My Documents\Development\autoUpdate\autoUpdateTest\Microsoft.ApplicationBlocks.ApplicationUpdater\BITSDownloader.cs:line 95

  at Microsoft.ApplicationBlocks.ApplicationUpdater.DownloaderFactory.Create(UpdaterConfiguration configuration) in c:\documents and settings\jroxas\my documents\development\autoupdate\autoupdatetest\microsoft.applicationblocks.applicationupdater\concretefactories.cs:line 61

any suggestions on how to clear this up?

# July 23, 2007 9:58 AM

Jerry said:

never mind, found it.  the problem had to do with the XmlNode config in the BITSDownloader.  it was trying to pull the userName, password, authenticationScheme and targetServerType from the config file, which did not include any of that information.  I commented this section of the code out, and it worked just fine.

# July 23, 2007 1:00 PM

Vishnuprem said:

Hi

 This steps were useful. Eventhough the source and destination path are correct, I found the error on the log file as

[DownloaderManager.DownloadApplicationFiles] :

SOURCE: 'localhost/.../SampleAssembly.exe'

DEST:   'C:\Program Files\MicrosoftUpdaterBlock\Code\DemoFiles\ConsoleClient1\newFiles\SampleAssembly.exe'

[DownloaderManager.DownloadApplicationFiles] :

SOURCE: 'localhost/.../SampleAssembly.exe.config'

DEST:   'C:\Program Files\MicrosoftUpdaterBlock\Code\DemoFiles\ConsoleClient1\newFiles\SampleAssembly.exe.config'

[DownloaderManager.DownloadApplicationFiles] :

SOURCE: 'localhost/.../SampleAssembly.pdb'

DEST:   'C:\Program Files\MicrosoftUpdaterBlock\Code\DemoFiles\ConsoleClient1\newFiles\SampleAssembly.pdb'

[DownloaderManager.BeginFileDownloads] :

   Status updated with job id 'd87c62b2-a441-4dbe-b4a6-75eb0a22b44a' for the application 'ConsoleTest1'.

[BITSDownloader] :

   The BITS service returned an error for the job with the ID 'd87c62b2-a441-4dbe-b4a6-75eb0a22b44a';

the job's name and description are 'BITS_Files_Download_Job' and 'BITS_Files_Download_Job'.  

The BITS service error message for this job is

'An unexpected condition prevented the server from fulfilling the request.

'.

This job has been canceled, and the DownloaderManager will attempt it again.  If you see this error frequently, you may have a mis-configuration, or another

administrator process/user is canceling BITS jobs.

It is also possible that some mis-configuration of the Manifest file is causing BITS to have trouble with a source or destination path;

be sure that all SOURCE paths are valid URLs, and that all DESTINATION paths are valid LOCAL UNC paths--__shares are not allowed__.

Anybody please help me out

Thanks

# December 6, 2007 7:34 AM

Rolle said:

Is it possible to use this updater block to update a windows service? (insted of only updating a WinForm ie)

Thanks for a nice article!

# December 31, 2007 7:58 AM

QuintusW said:

HI the updater work very nice...Just a question what about all the Microsoft dll's.

If I don't copy them manuly into the version folder the app doesn't run

(Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces

....

....)

Thanks

# May 16, 2008 4:09 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors