File Download with ProgressBar for Windows Forms
Note: Code is .NET 1.1
For a previous web project of mine, I built a web-based application update component that permitted the Webmaster to initiate software and database updates through a browser with a few button clicks (no manual file copy, etc...).
This of course involves having some sort of file download routine to copy the Update package from my server to a customer's server - and be managed through a Webform.
Downloading files in .NET is simple as a few lines of code using the WebClient or WebRequest and WebResponse Classes - but I also want to have a progress bar in the Webform.
Anyway, after much Googling for some sample code that included progress bars, the best I could find was some VB.NET examples for Windows Forms applications.
I found some working VB.NET code to download (credit to Mike McIntyre) from DevCity.NET. I transposed this VB.NET sample into C# (sample below), from which I'll base my ASP.NET implementation on (for another article) - allowing of course for how HTTP will push progress information to the Webform.
The credit also goes to this forum posting, where I think most of code originated. I just put it into a working Windows Forms application written in C#.
Download VS.NET 2003 C# Project - DemoDownloadProgressBar.zip (28.29 KB)
Following is an excerpt of the code.
private bool download(string path_download, string path_local){
// Declare a variable of type Boolean named result initialized to false.
bool result = false;
// Declare a variable of type HttpWebRequest named lHttpWebRequest.
HttpWebRequest lHttpWebRequest;
// Declare a variable of type HttpWebResponse named lHttpWebResponse.
HttpWebResponse lHttpWebResponse;
// Declare a variable of type Stream named lHttpWebResponseStream.
Stream lHttpWebResponseStream;
// Declare a variable of type FileStream named lFileStream.
// Use a FileStream constructor to create a new FileStream object.
// Assign the address (reference) of the new object
// to the lFileStream variable.
FileStream lFileStream = new FileStream(path_local, FileMode.Create);
// Declare a variable of type Byte Array named byteBuffer.
byte[] byteBuffer = new byte[999];
// Declare a variable of type Integer named bytesRead.
int bytesRead;
try{
// Instantiate the HttpWebRequest object.
lHttpWebRequest = (HttpWebRequest)WebRequest.Create(path_download);
// Instantiate the HttpWebRespose object.
lHttpWebResponse = (HttpWebResponse)lHttpWebRequest.GetResponse();
// Instantiate the ResponseStream object.
lHttpWebResponseStream = lHttpWebRequest.GetResponse().GetResponseStream();
// Set the ProgressBars Maximum property equal to the length of the file
// to be downloaded.
progressBar1.Maximum = Convert.ToInt32(lHttpWebResponse.ContentLength);
// progress counter to control when
// the form label is updated
double progress_counter = 0;
do{
// Read up to 1000 bytes into the bytesRead array.
bytesRead = lHttpWebResponseStream.Read(byteBuffer, 0, 999);
// Write the bytes read to the file stream.
lFileStream.Write(byteBuffer, 0, bytesRead);
// If the ProgressBar's value plus bytesRead is less than the length of the file...
if((progressBar1.Value + bytesRead) <= progressBar1.Maximum){
// Add bytesRead to the ProgressBar's Value property.
progressBar1.Value += bytesRead;
}else{
// Else files download is done so set ProgressBar's Value to the length of the file.
progressBar1.Value = progressBar1.Maximum;
}
// calculate the current percentage
double progress_now = Math.Floor(((progressBar1.Value/100) * 100) / (progressBar1.Maximum/100));
// only upgrade the display label once per percentage increment
if(progress_now > progress_counter){
// Update the ProgressLabel.
label3.Text = String.Format("{0}% of {1}kb", progress_now.ToString(), (progressBar1.Maximum/1000).ToString("#,#"));
// update the form
Application.DoEvents();
// increment the counter
progress_counter++;
}
}while(bytesRead > 0);
// Close the file and web response streams.
lHttpWebResponseStream.Close();
// Set result to True - download was successful.
result = true;
}catch(Exception download_error){
// display the whole error
MessageBox.Show(download_error.ToString());
}finally{
// Close the file and web response streams.
lFileStream.Close();
}
return result;
}
I changed a few things, like the percentage math for larger files. I was testing with a 38mb file and it caused some arithmetic errors on the huge decimal values it was creating. As well, I added a percentage counter so that the Label control was only updated once for each percent increment (about 100 times), as opposed to the 38,000,000 times the control was updated on my large test file, based on the original code.
Hope this is of use...
Note: This article is a repost from my original.

Nice site Scooter
Posted by: Ricky | Saturday, September 23, 2006 at 01:01 PM
Nice example!
However, I can't help but notice that the length of your comments greatly exceeds the length of the code you write.
"// Declare a variable of type HttpWebResponse named lHttpWebResponse.
HttpWebResponse lHttpWebResponse;"
A comment like that really adds no value and makes the code LESS readable, rather than the other way around.
Really!
Posted by: Erik | Tuesday, September 04, 2007 at 09:35 AM
Hey Erik, you're a dork!
You don't like it, then go get your code somewhere else.
Posted by: Scott | Tuesday, September 04, 2007 at 11:34 AM
Heartly thanks sir, you don't know how help ur code is for me. I am a software engineer working in Mobile Technology and new comer also. Once again thanks.
Regards,
Partha (The Name Everyone Needs)
Posted by: Partha Sarathi Thatoi | Thursday, April 10, 2008 at 04:51 AM