Click here to Skip to main content
13,834,348 members
Click here to Skip to main content
Add your own
alternative version


37 bookmarked
Posted 14 Oct 2007
Licenced CPOL

Problem: ClickOnce Deployment via Internet May Not Always Upgrade an Application

, 30 Oct 2007
Rate this:
Please Sign up or sign in to vote.
An application deployed using ClickOnce may not receive an upgrade if the browser’s proxy server has cached the deployment file. This article explains how to solve this problem using HTTP content expiration.


An application deployed using ClickOnce may not receive an upgrade if the browser's proxy server has cached an older deployment file. This article explains how to solve this problem using HTTP content expiration.


Let's assume you have deployed an application, called TestAppForClickOnce, via ClickOnce on a host Website. The metadata file named TestAppForClickOnce.application is the primary download artifact for clients to install this application.

The default expiration settings on the host Website (using IIS) will cause TestAppForClickOnce.application to have no expiry. Depending on what type of firewall is used in the client network, a copy of TestAppForClickOnce.application will be cached there after the client browser downloads this file. Subsequent requests from the same browser or any other browsers using the same proxy settings, will receive the cached copy of that file.

A new version of TestAppForClickOnce may be hosted on the host Website and this is done using a new version of TestAppForClickOnce.application. The client upgrade is triggered during application launch or by the user accessing the TestAppForClickOnce.application directly from the host Website. Since TestAppForClickOnce.application is not interpreted as dynamic content, the cached version is passed to the client browser and a new version of the file will not be downloaded from the host Website. This means some clients will not receive your version upgrade.

Depending on conditions within the firewall, the TestAppForClickOnce.application file may be dropped from the cache and this inadvertently allows the new application version through. However, this does not present a good solution because it is not clear how long the new application version will remain inaccessible.

Using the Code

Solution: Explicitly set expiry of all ClickOnce deployment files.

Since cached ClickOnce deployment files present a big problem for upgrades, a solution is offered here. The primary solution is to explicitly set the expiry of ClickOnce deployment files. The detailed solution below chooses to set the expiry to "immediate" and implements this expiry using the Web.config file within a .NET 2.0 Website. You may also use IIS to set the expiry of each file in a Website but not all Web hosting providers have this option available. Other Web hosting technologies offer alternative expiry implementations, but they are not covered in this solution.

Step 1: In the Web.config file, add an HTTP handler.

<?xml version="1.0"?>
<location path="Downloads">
<add verb="*" path="*.*" type="CustomHttpHandlers.ClickOnceApplicationHandler"/>

Step 2: Create a class named ClickOnceApplicationHandler with namespace CustomHttpHandlers.

Step 3: Make ClickOnceApplicationHandler inherit from IHttpHandler.

Step 4: Implement the ProcessRequest members.

void IHttpHandler.ProcessRequest(HttpContext context)
string path = context.Server.MapPath(context.Request.Path).ToLower();
if (File.Exists(path))
//Ensure browser handles application files correctly
if (path.EndsWith(".application")) context.Response.ContentType =
byte[] outputBinaryArray;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
outputBinaryArray = r.ReadBytes(Convert.ToInt32(fs.Length));
throw new HttpException(404, "File not found");


What This Solution Has Achieved

The above solution ensures that well-behaved firewalls do not cache ClickOnce deployment files.

What This Solution Does Not Achieve

If a firewall server has already cached any ClickOnce deployment files, the above solution does not expire them. When a file is cached, the firewall does not retrieve a new copy from the host Website and therefore the original expiration settings remain. In this case, the firewall cache needs to be manually purged, but most often this cannot be done by authors of the host Website.

My advice is to implement the above expiration solution as soon as possible to ensure none of your customers get affected by cached ClickOnce files.

To test some ClickOnce applications using the above caching solution, visit Coded Silicon.


One caveat that makes this solution less independent from IIS settings is that IIS does not by default map .application files to ASP.NET.
So to make this solution work, you still need to change the settings in IIS.

The change in settings is as follows:
In the application mapping properties, add a mapping for .application to run using
(Path may be different on your server).

So if you had to tweak the settings in IIS, why not set the expiration settings directly in IIS (under HTTP Headers)?
Setting the expiration settings directly in IIS is a viable quick solution, but using an HTTP handler provides better control over caching. The HTTP handler solution allows us to selectively modify the cache settings of .application files only or to selectively modify the cache settings of the files in a particular folder.


  • 15th October, 2007 -- Original version posted
  • 25th October, 2007 -- Caveat added


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Johan Fourie
Australia Australia
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionSo do I just create a ClickOnceApplicationHandle.cs file and add the code to it? Pin
Beaner23-Jul-12 6:10
memberBeaner23-Jul-12 6:10 
Questionhtaccess override for Apache servers Pin
Long Zheng3-Nov-11 19:32
memberLong Zheng3-Nov-11 19:32 
GeneralQuestion Pin
Member 579813713-Jun-11 14:45
memberMember 579813713-Jun-11 14:45 
Generalwhen the website is down Pin
Ravi Tejas21-Nov-08 1:21
memberRavi Tejas21-Nov-08 1:21 
AnswerRe: when the website is down Pin
Johan Fourie23-Nov-08 12:08
memberJohan Fourie23-Nov-08 12:08 
GeneralRe: when the website is down Pin
Ravi Tejas24-Nov-08 0:28
memberRavi Tejas24-Nov-08 0:28 
GeneralRe: when the website is down Pin
Johan Fourie26-Nov-08 17:01
memberJohan Fourie26-Nov-08 17:01 
GeneralRe: when the website is down Pin
Ravi Tejas27-Nov-08 22:46
memberRavi Tejas27-Nov-08 22:46 
GeneralRe: when the website is down Pin
Johan Fourie28-Nov-08 20:09
memberJohan Fourie28-Nov-08 20:09 
GeneralOneclick cache issue using IIS Pin
comasic24-Oct-07 14:50
membercomasic24-Oct-07 14:50 
GeneralRe: Oneclick cache issue using IIS Pin
Johan Fourie24-Oct-07 17:11
memberJohan Fourie24-Oct-07 17:11 
GeneralPerhaps it could be simplified Pin
Georged17-Oct-07 5:01
memberGeorged17-Oct-07 5:01 
GeneralRe: Perhaps it could be simplified Pin
Johan Fourie17-Oct-07 13:33
memberJohan Fourie17-Oct-07 13:33 
QuestionHow to download a group of files by force? Pin
Michael Sync16-Oct-07 18:54
memberMichael Sync16-Oct-07 18:54 
AnswerRe: How to download a group of files by force? Pin
Johan Fourie16-Oct-07 21:27
memberJohan Fourie16-Oct-07 21:27 
GeneralRe: How to download a group of files by force? Pin
Michael Sync16-Oct-07 21:38
memberMichael Sync16-Oct-07 21:38 
GeneralRe: How to download a group of files by force? Pin
hannesk23417-Oct-07 7:04
memberhannesk23417-Oct-07 7:04 
GeneralRe: How to download a group of files by force? Pin
Johan Fourie17-Oct-07 13:38
memberJohan Fourie17-Oct-07 13:38 
Generalgreat.. Pin
Michael Sync15-Oct-07 0:48
memberMichael Sync15-Oct-07 0:48 
GeneralRe: great.. Pin
Johan Fourie16-Oct-07 13:45
memberJohan Fourie16-Oct-07 13:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190114.1 | Last Updated 30 Oct 2007
Article Copyright 2007 by Johan Fourie
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid