Geekpedia Programming Tutorials






Creating an advanced download manager in C#

In this tutorial we are extending a previously created download manager with progress indicator. Among improvements to the previous code, we are adding the code that allows the user to pause and resume a download.

On Sunday, October 1st 2006 at 05:01 PM
By Andrew Pociu (View Profile)
*****   (Rated 4.8 with 40 votes)
Contextual Ads
More C# Resources
Advertisement
Download this Visual Studio 2005 project Download this project (Visual Studio 2005)

This is a continuation of the tutorial entitled "Creating a download manager in C#" in which we created a Windows application that was capable of downloading files via the http:// protocol and showing the progress of retrieving the bytes from the server to the local computer. In this tutorial we'll see how we can put additional functionality into this application, by adding code that allows the user to pause and resume a download.

If you didn't read the previous tutorial, you should, otherwise you will not understand much of this one since we'll be developing on top of the code explained in the first tutorial. For the sake of consistency, we will name the application we build in this tuorial "DownloadManager2" as to not be confused with the one that we wrote in the first tutorial, which was entitled "DownloadManager". However, you should feel free to add the code from this tutorial to the old application.

To allow the user to pause and resume the download, we can't just suspend and resume the thread in which the downloading process is running, because that would leave an open connection between the PC and the server from where the file is download. The approach that we're looking for is to close the file and close the stream when the user presses the Pause button. Then, when he presses Resume, we check for the file path and if the file exists (and it should if he paused, because the partially downloaded file got written to the hard-drive), we get its size. Now that we know its size, we know from what point to move on with the downloading. Therefore we open a new connection to the server providing the file and ask it to stream the data to us, but starting from a certain point (using AddRange()), and that point is the same as the file size. The logic here is simple, we downloaded until let's say byte 314,159 and paused. This means the file on the hard drive now has 314,159 bytes. When it is resumed, the file size is the same as the point where we stopped, so we continue getting the bits of data after the byte 314,159 and append them to the partially downloaded file until the stream is complete orthe user pauses the download again.

The only visible change done to the form is the addition of a "Pause" button which will change itself to "Resume" when clicked. The button is named btnPauseResume. Set its Enabled property to False, since we don't want the button enabled until a download has been started.

Download Manager Form

Now that you added this button switch to code view and the first changes we need to make to the previous Dowload Manager project is to create a boolean variable that when set to true, the loop that downloads from the server will stop. You should define this variable next to the other variables from the previous project (the old code is colored gray, you can ignore it):


// The thread inside which the download happens

private Thread thrDownload;

// The stream of data retrieved from the web server

private Stream strResponse;

// The stream of data that we write to the harddrive

private Stream strLocal;

// The request to the web server for file information

private HttpWebRequest webRequest;

// The response from the web server containing information about the file

private HttpWebResponse webResponse;

// The progress of the download in percentage

private static int PercentProgress;

// The delegate which we will call from the thread to update the form

private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);

// When to pause

bool goPause = false;


By default the variable is set to false so that the download starts and continues normally.
The next in our code came the btnDownload_Click event where the download thread was being started. Since we're doing some changes to the code for the pause/resume functionality, we're also adding an if/else condition that checks wether or not a download is already in progress. If it is, we don't want the user to press Download again. He can either pause or stop the download, but he should not be able to start another download while one is already in progress. Since we're changing pretty much all the code inside btnDownload_Click, erase all the content inside this event and use this new one:


if (thrDownload != null && thrDownload.ThreadState == ThreadState.Running)

{

    MessageBox.Show("A download is already running. Please either the stop the current download or await for its completion before starting a new one.", "Download in progress", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

else

{

    // Let the user know we are connecting to the server

    lblProgress.Text = "Download Starting";

    // Create a new thread that calls the Download() method

    thrDownload = new Thread(new ParameterizedThreadStart(Download));

    // Start the thread, and thus call Download(); start downloading from the beginning (0)

    thrDownload.Start(0);

    // Enable the Pause/Resume button

    btnPauseResume.Enabled = true;

    // Set the button's caption to Pause because a download is in progress

    btnPauseResume.Text = "Pause";

}


First we check to see if the thread was created and if it's started. If it is, a download must already be in progress, so we let the user know about that.
Otherwise, what we're doing different in this event from the previous project is that we start the thread differently (using ParameterizedThreadStart), because now we need to pass a parameter to it. The parameter specifies the point at which we want to start the download. Because when the user presses Download, the download is always started from the beginning (unlike when he presses Resume), the parameter passed is 0, and you can see that on the next line. The last lines are simply enabling the Pause/Resume button so that the user can Pause the download; we also set its caption to "Pause" because that's what the button will be doing at this point.

The next comes the UpdateProgress method that is left unchanged from the previous project. Now let's have a look at the new Download method that suffered the most changes, and which does the actual resuming:


private void Download(object startPoint)

{

    try

    {
        // Put the object argument into an int variable

        int startPointInt = Convert.ToInt32(startPoint);

        // Create a request to the file we are downloading

        webRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);

        // Set the starting point of the request

        webRequest.AddRange(startPointInt);

 

        // Set default authentication for retrieving the file

        webRequest.Credentials = CredentialCache.DefaultCredentials;

        // Retrieve the response from the server

        webResponse = (HttpWebResponse)webRequest.GetResponse();

        // Ask the server for the file size and store it

        Int64 fileSize = webResponse.ContentLength;

 

        // Open the URL for download

        strResponse = webResponse.GetResponseStream();

 

        // Create a new file stream where we will be saving the data (local drive)

        if (startPointInt == 0)

        {

            strLocal = new FileStream(txtPath.Text, FileMode.Create, FileAccess.Write, FileShare.None);

        }

        else

        {

            strLocal = new FileStream(txtPath.Text, FileMode.Append, FileAccess.Write, FileShare.None);

        }

 

        // It will store the current number of bytes we retrieved from the server

        int bytesSize = 0;

        // A buffer for storing and writing the data retrieved from the server

        byte[] downBuffer = new byte[2048];

 

        // Loop through the buffer until the buffer is empty

        while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)

        {

            // Write the data from the buffer to the local hard drive

            strLocal.Write(downBuffer, 0, bytesSize);

            // Invoke the method that updates the form's label and progress bar

            this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize + startPointInt });

 

            if (goPause == true)

            {

                break;

            }

        }

    }

    finally

    {

        // When the above code has ended, close the streams

        strResponse.Close();

        strLocal.Close();

    }

}


First, we drop the WebClient object from the previous project since instead of using the OpenRead method of the WebClient, we are now using the GetResponseStream method of the HttpWebResponse object to get the data from the URL into a stream. This might not be necessary, however it is an improvement that we create an object less in our new version.

A new line in the Download method is webRequest.AddRange(startPointInt); which does most of the work: it tells the server the range from which the download should start and end. This will be different than 0 only when we resume an existing download, otherwise we want the file from the very beginning. The variable that specified the starting point is startPointInt which was passed to the method as a parameter. You'll see later when we call this method with the parameter that the starting point is the same as the size of the existing file. If there's no existing file, there's no resume, so we start from 0. We don't specify an ending point in the range, because we're interested in the entire file.

The next change that is very important to note is that we check if the starting point of the download is 0, and if it is we create the file stream normally, like we did in the previous project. However, if it's not, we specify a different parameter when creating the FileStream object: FileMode.Append - because we want to append the data from the server to the existing file.

Last thing to be noted in this method is the new if condition in the while loop, that checks each and every loop if the goPause variable has been set to true. It if has, we break out of the loop because this variable is set to true only when we wish to stop (pause) the download. Therefore, even though the button is named Pause, what it actually does is to stop the download completely, not leave it in a hanging state. Leaving connections open with the server would be bad, and they would eventually time out. So pressing Pause is similar to pressing the Stop button - but then why do they take similar approaches to stopping the download? If you look in the btn_Stop event, you'll see that instead of breaking out of the while loop that retrieves bytes of data from the server, we are aborting the thread all together. This can be a harsh approach, and data could get corrupted, we would not know for sure when the thread has actually stopped, at which exact loop; and since we're planning to resume the file later, we need to be sure the download stopped in good terms.

Next comes the btnStop_Click event that it's changed just a little: the line that aborts the method is put first, and then the streams are closed. This prevents the streams from being closed before the thread has really aborted. The thread might still try to access the streams and we don't want that. One other thing we do is to disable the Pause / Resume button, which makes sence, since the download was fully stopped, there is no such functionality anymore.


// Abort the thread that's downloading

thrDownload.Abort();

// Close the web response and the streams

webResponse.Close();

strResponse.Close();

strLocal.Close();

// Set the progress bar back to 0 and the label

prgDownload.Value = 0;

lblProgress.Text = "Download Stopped";

// Disable the Pause/Resume button because the download has ended

btnPauseResume.Enabled = false;


Next comes a big piece of code that is the new btnPauseResume_Click event. So you should double click the button in the form designer to create the new event automatically, and inside it you should use the following code:


private void btnPauseResume_Click(object sender, EventArgs e)

{

    // If the thread exists

    if (thrDownload != null)

    {

        if (btnPauseResume.Text == "Pause")

        {

            // The Pause/Resume button was set to Pause, thus pause the download

            goPause = true;

 

            // Now that the download was paused, turn the button into a resume button

            btnPauseResume.Text = "Resume";

 

            // Close the web response and the streams

            webResponse.Close();

            strResponse.Close();

            strLocal.Close();

            // Abort the thread that's downloading

            thrDownload.Abort();

        }

        else

        {

            // The Pause/Resume button was set to Resume, thus resume the download

            goPause = false;

 

            // Now that the download was resumed, turn the button into a pause button

            btnPauseResume.Text = "Pause";

 

            long startPoint = 0;

 

            if (File.Exists(txtPath.Text))

            {

                startPoint = new FileInfo(txtPath.Text).Length;

            }

            else

            {

                MessageBox.Show("The file you choosed to resume doesn't exist.", "Could not resume", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }

 

            // Let the user know we are connecting to the server

            lblProgress.Text = "Download Resuming";

            // Create a new thread that calls the Download() method

            thrDownload = new Thread(new ParameterizedThreadStart(Download));

            // Start the thread, and thus call Download()

            thrDownload.Start(startPoint);

            // Enable the Pause/Resume button

            btnPauseResume.Enabled = true;

        }

    }

    else

    {

        MessageBox.Show("A download does not appear to be in progress.", "Could not pause", MessageBoxButtons.OK, MessageBoxIcon.Error);

    }

}


The code along with the comments should be self explanatory. We first check to see if the buttons are set to pause or resume the download by looking at their caption, and then take the proper action.

Download Manager Application Window

Hoping that we improved the application enough in this tutorial, I'm going to end it here. You should be aware that if you are looking to turn this into a fully functional and reliable download manager, there are several checks and tweaks that you need to apply to the code, since there are a couple of known problems that can break the application. For example if the Pause/Resume button is clicked repeatedly very fast, it can result in an exception. This will rarely happen, though you'll want to prevent or catch this exception.

If there's sufficient demant, a third part of this tutorial will follow in which we manage a list of downloads and allow multiple downloads at once.
Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by on Sunday, October 1st 2006 at 07:53 PM

Excellent, and thanks.

A couple questions however:

1. If I try calling the download thread, and then have an autoreset event to pause until the download is finished, the code locks up at the invoke event. How can I call the download thread, pause where Im at in my code until the download is done, but still update the progress bar?

Im using something like this:

AutoResetEvent threadRunning = new AutoResetEvent (false);

thrDownload.Start();

threadRunning.WaitOne();

And at the end of the download method I simply added:

threadRunning.Set();


2. I think there is a bug in that if you download the same file twice, it locks up. I believe the “finally” .close functions are perhaps doing something they should be?

by Will on Tuesday, November 21st 2006 at 09:11 PM

How would I enable this to report the kbps?
--
Great work so far.
--

by on Friday, December 1st 2006 at 01:50 AM

b

by James on Thursday, January 4th 2007 at 02:03 PM

So why don\'t you use the background worker or a Command Pattern?

by James on Thursday, January 4th 2007 at 10:29 PM

Hi Andrei Pociu; I figured I would redo this whole application and take advantage of the BackgroundWorker! I would like to post up my final piece if it's possible :) !! I hadn't noticed a way to be able to post an article; but I wouldn't mind writing up some nice articles here and help this site grow some, as I can tell y'all don't have a lot of spare time to do what I'm sure you'd like to accomplish here! I'll be checking back here to see if you've posted a reply as I don't want to post my email address here! And thus far your article(s) are good as is for beginners but I'd like to help them get through to the next level of this application; It's an interesting application and is a great way for beginners to keep on keeping on...
---
James

by Andrei Pociu on Thursday, January 4th 2007 at 10:55 PM

Hello James,

New and improved tutorials are always welcome. First you need to register at http://www.geekpedia.com/register.php. After you sign in you can add a new tutorial via the author panel. Alternatively after signing up you can email the tutorial at support@geekpedia.com in any format you want and it will be formatted into HTML and posted on Geekpedia under your account, shortly.

Please email support@geekpedia.com and I can give you more details.

by Vivek on Monday, February 12th 2007 at 02:15 AM

Great work!
Please post an article for the following
Multiple file download at once.

Thank You.

by James on Tuesday, April 17th 2007 at 09:17 PM

I wrote a version using the BackgroundWorker pattern here:
http://www.bytemycode.com/snippets/snippet/644/

I was going to add it to this site but it's a pain as I noticed creating tutorials here there is no way I noticed to preview the code first and there is a waiting period which I didn't like much!

--James--

by Scott Anderson on Tuesday, April 24th 2007 at 12:21 PM

Andrei,

When using this code, I\'ve noticed that the download seems to freeze at the same spot for me almost all the time. Everything works perfectly up until about 1.11 MB are downloaded, and then the download stops, but no exceptions are thrown. The application just simply stops doing anything.

Do you have any ideas about how I can fix this?

Thanks
Scott

by sudharshanreddy on Thursday, June 21st 2007 at 08:32 AM

how can pass the download when server down
how can i restart when server up

pls reply soon

by Josh Dawkins on Monday, June 25th 2007 at 06:45 AM

I too was wondering how you could convert the file size into Kbps, or even Mbps for larger files. I didn't notice a response, so I was hoping to jog your memory. Do you have any ideas?

Please reply soon.

by bikram shome on Tuesday, August 7th 2007 at 07:50 AM

i want to controll the speed of download ,how it can be possible if u have any suggestion plz suggest me i will be very much thankfull to u.....

by derrick on Thursday, August 9th 2007 at 07:26 PM

I'm interested in part 3!

by dave on Saturday, August 25th 2007 at 11:21 PM

can u add tutorial about website filter? I really want to learn that.

by Roland on Monday, August 27th 2007 at 10:15 PM

Great work! However, I do notice that when I try to download one particular mp3 file. During the download, I tried to pause, resume, pause and resume again, the download becomes haywire. When the download is completed, the file is corrupted.

by Chakravarthi on Wednesday, September 26th 2007 at 06:43 AM

How can I download a single file with multiple threads in chunks?

by Rothariger on Wednesday, October 3rd 2007 at 08:56 PM

hi, what about if the server does not support resume???


by!

by tom on Tuesday, October 9th 2007 at 04:20 PM

One problem.

webRequest.AddRange() only takes int32 values. Largest file you can download is 2,147,483,647 bytes =~ 2.1 gigs. After that you get an exception and you cant pass in int64 values either.

If anyone has a solution for this, it would be greatly appreciated.

by Andrei Pociu on Tuesday, October 9th 2007 at 04:34 PM

Thanks for pointing that out, Tom. That's an interesting limitation that the HttpWebRequest object has, I'll look into it.

by feral on Sunday, November 4th 2007 at 04:24 PM

well commented and cleanly coded thanks

@ tom - yes it sucks that add range doesnt have an overload for int64/long and adding a range header \"breaks\" the request

by on Saturday, December 29th 2007 at 02:14 PM

FULL OF ERRORS:

you can not call thread.abort and assume in the next line that it has indeed been already aborted.

run the code and hit quickly: pause and then download. it will block !

by toFrenchy on Saturday, December 29th 2007 at 02:55 PM

To the last guy who commented - that has been mentioned in the tutorial. Did you actually read the tutorial?

by Paul on Tuesday, January 29th 2008 at 06:01 PM

you can double the limitation to 4 Gigs if you use both positive and negative numbers for the range

If range is positive, the range is from the start of the data to range.

If range is negative, the range is from range to the end of the data.

by live2 on Sunday, February 10th 2008 at 10:11 AM

Now you can close the Application and then start again the download at the last position

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;

namespace DownloadManager2
{
public partial class Form1 : Form
{
// The thread inside which the download happens
private Thread thrDownload;
// The stream of data retrieved from the web server
private Stream strResponse;
// The stream of data that we write to the harddrive
private Stream strLocal;
// The request to the web server for file information
private HttpWebRequest webRequest;
// The response from the web server containing information about the file
private HttpWebResponse webResponse;
// The progress of the download in percentage
private static int PercentProgress;
// The delegate which we will call from the thread to update the form
private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);
// When to pause
bool goPause = false;

public Form1()
{
InitializeComponent();
}

private void btnDownload_Click(object sender, EventArgs e)
{
long startPoint = 0;

if (thrDownload != null && thrDownload.ThreadState == ThreadState.Running)
{
MessageBox.Show(\"A download is already running. Please either the stop the current download or await for its completion before starting a new one.\", \"Download in progress\", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (File.Exists(txtPath.Text))
{
startPoint = new FileInfo(txtPath.Text).Length;
}

// Let the user know we are connecting to the server
lblProgress.Text = \"Download Starting\";
// Create a new thread that calls the Download() method
thrDownload = new Thread(new ParameterizedThreadStart(Download));
// Start the thread, and thus call Download(); start downloading from the beginning (0)
thrDownload.Start(startPoint);
// Enable the Pause/Resume button
btnPauseResume.Enabled = true;
// Set the button\'s caption to Pause because a download is in progress
btnPauseResume.Text = \"Pause\";
}
}

private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
{
// Calculate the download progress in percentages
PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);
// Make progress on the progress bar
prgDownload.Value = PercentProgress;
// Display the current progress on the form
lblProgress.Text = \"Downloaded \" + BytesRead + \" out of \" + TotalBytes + \" (\" + PercentProgress + \"%)\";
}

private void Download(object startPoint)
{
try
{
HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
webRequest1 = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
webRequest1.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse webResponse1 = (HttpWebResponse)webRequest1.GetResponse();
Int64 fileSize1 = webResponse1.ContentLength;
webRequest1.Abort();
webResponse1.Close();


// Put the object argument into an int variable
int startPointInt = Convert.ToInt32(startPoint);
// Create a request to the file we are downloading
webRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
// Set the starting point of the request
webRequest.AddRange(startPointInt);

// Set default authentication for retrieving the file
webRequest.Credentials = CredentialCache.DefaultCredentials;
// Retrieve the response from the server
webResponse = (HttpWebResponse)webRequest.GetResponse();
// Ask the server for the file size and store it
Int64 fileSize = webResponse.ContentLength;

if (startPointInt >= fileSize1)
{
return;
}

// Open the URL for download
strResponse = webResponse.GetResponseStream();

// Create a new file stream where we will be saving the data (local drive)
if (startPointInt == 0)
{
strLocal = new FileStream(txtPath.Text, FileMode.Create, FileAccess.Write, FileShare.None);
}
else
{
strLocal = new FileStream(txtPath.Text, FileMode.Append, FileAccess.Write, FileShare.None);
}

// It will store the current number of bytes we retrieved from the server
int bytesSize = 0;
// A buffer for storing and writing the data retrieved from the server
byte[] downBuffer = new byte[2048];

// Loop through the buffer until the buffer is empty
while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
// Write the data from the buffer to the local hard drive
strLocal.Write(downBuffer, 0, bytesSize);
// Invoke the method that updates the form\'s label and progress bar
this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize1 });

if (goPause == true)
{
break;
}
}
}
finally
{
// When the above code has ended, close the streams
if (strResponse != null)
{
strResponse.Close();
strLocal.Close();
}
}
}

private void btnStop_Click(object sender, EventArgs e)
{
// Abort the thread that\'s downloading
thrDownload.Abort();
// Close the web response and the streams
webResponse.Close();
strResponse.Close();
strLocal.Close();
// Set the progress bar back to 0 and the label
prgDownload.Value = 0;
lblProgress.Text = \"Download Stopped\";
// Disable the Pause/Resume button because the download has ended
btnPauseResume.Enabled = false;
}

private void btnPauseResume_Click(object sender, EventArgs e)
{
// If the thread exists
if (thrDownload != null)
{
if (btnPauseResume.Text == \"Pause\")
{
// The Pause/Resume button was set to Pause, thus pause the download
goPause = true;

// Now that the download was paused, turn the button into a resume button
btnPauseResume.Text = \"Resume\";

// Close the web response and the streams
webResponse.Close();
strResponse.Close();
strLocal.Close();
// Abort the thread that\'s downloading
thrDownload.Abort();
}
else
{
// The Pause/Resume button was set to Resume, thus resume the download
goPause = false;

// Now that the download was resumed, turn the button into a pause button
btnPauseResume.Text = \"Pause\";

long startPoint = 0;

if (File.Exists(txtPath.Text))
{
startPoint = new FileInfo(txtPath.Text).Length;
}
else
{
MessageBox.Show(\"The file you choosed to resume doesn\'t exist.\", \"Could not resume\", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

// Let the user know we are connecting to the server
lblProgress.Text = \"Download Resuming\";
// Create a new thread that calls the Download() method
thrDownload = new Thread(new ParameterizedThreadStart(Download));
// Start the thread, and thus call Download()
thrDownload.Start(startPoint);
// Enable the Pause/Resume button
btnPauseResume.Enabled = true;
}
}
else
{
MessageBox.Show(\"A download does not appear to be in progress.\", \"Could not pause\", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

by Andy on Wednesday, March 26th 2008 at 04:27 PM

i am receiving an error after the donwload is completed or whe I close the form...

Cannot access a disposed object.
Object name: \'Form1\'.


this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize1 });

by Punit Ganshani on Monday, April 7th 2008 at 07:06 AM

This error pops up when the ProgressBar has a value > 100.

Write a piece of snippet that assigns value to ProgressBar only if it is greater than 100 and the code will work perfectly.

www.ganshani.com

by Chris on Friday, April 25th 2008 at 01:23 AM

Please show the third part.

by ae on Tuesday, May 6th 2008 at 10:57 AM

Hi mister,

any solution about the comments ? another latest version ?

1).
you can double the limitation to 4 Gigs if you use both positive and negative numbers for the range

If range is positive, the range is from the start of the data to range.

If range is negative, the range is from range to the end of the data.


2.)
How can I download a single file with multiple threads in chunks?

3.)
webRequest.AddRange() only takes int32 values. Largest file you can download is 2,147,483,647 bytes =~ 2.1 gigs. After that you get an exception and you cant pass in int64 values either

thanks in advance

by JesusV on Monday, September 29th 2008 at 11:11 PM

Hi,

Would you have this DownloadManager in VB.NET?

Thank you.

Best Regards.

by Sachin on Thursday, November 6th 2008 at 02:07 PM

In some cases the webserver returns -1 for ContentLength.

Int64 fileSize = webResponse.ContentLength

fileSize is -1

by C-Sharper on Sunday, January 11th 2009 at 11:23 AM

First of all, thanks for a very good tutorial, but icant seem to find a solution on how to resume files which are bigger then int32?

Sachin:

That means the filesize isnt known, check webresponse headers form more info.


Also, alot of servers doesnt support addrange, so u might want to look at the httpresponse's status code, if it is ok, then it returns the whole file, else if it is partialcontent then it accpets addrange.

by reed on Thursday, January 15th 2009 at 04:59 PM

Thank you Andrew, this is exactly what I need

by ld on Tuesday, January 20th 2009 at 03:16 AM

Hi and thanks for the tutorial.

Part one is funcioning great but in the second one I get the following error message:

DownloadManager2.exe' does not contain a static 'Main' method suitable for an entry point.

Anyone having an idea?

I would be very grateful!


by Zohaib on Friday, January 30th 2009 at 01:07 PM

Hello!

I have done all with ur tutorial. Also I have used SQL Server to add the progress and received bytes but TELL ME HOW?

Can I run multiple threads to download single file and how will I be able to know exact resume point of each segment.

As here FILE_STREAM.ContentLength()

BUT HOW FOR EACH SEGMENT?

Thanx

by Zohaib on Friday, January 30th 2009 at 01:10 PM

Hello!

I have done all with ur tutorial. Also I have used SQL Server to add the progress and received bytes but TELL ME HOW?

Can I run multiple threads to download single file and how will I be able to know exact resume point of each segment.

As here FILE_STREAM.ContentLength()

BUT HOW FOR EACH SEGMENT?

Thanx

by sadf on Wednesday, February 11th 2009 at 11:41 PM

get the filesize first n then calculate segments.....

by Minh Moron on Wednesday, February 18th 2009 at 05:36 AM

Thank a lot. I'm looking for the 3rd part and how to manage using multi threads to download 1 file (as download accelerating applications do).

by nadiahkamil on Wednesday, February 25th 2009 at 02:20 AM

This is interesting...
Please continue the 3rd part....
I'm waiting...
multithread is challenging....i really want to learn it

by Hal on Friday, March 6th 2009 at 02:31 PM

I am also interested in part 3 of this tutorial.

Regards,
Hal

by Fon on Tuesday, May 5th 2009 at 07:04 PM

Very interesting!!

Looking forward for the 3rd part.

Regards. Fon.

by espinete on Wednesday, May 6th 2009 at 01:48 AM

Oh, yeah !! 3rd part, please !! for God !!!

thanks

by Rickey on Sunday, May 17th 2009 at 09:27 PM

I wrote a similar application as this a while back, it was a very simple application, but it allowed for multiple downloads at once, it was very simple to do because I created a separate form that handled all the downloading, and created the additional thread after being passed the paths. so you could just keep creating new instances of that 2nd form and it would be downloading more files. you just past in the url and click download and a save as dialog appeared, asked where to save it, with the extention already written in.

andyone wants a copy just request.

by espinete on Monday, May 18th 2009 at 01:18 AM

please mister Rickey, Irequest for a copy

thanks

send me, please, anonimoatacante AT yahoo DOT es

at = @
dot = .

by Fon on Monday, May 18th 2009 at 01:32 AM

I want the copy to mr. Rickey. d.n.a.core@gmailDOTcom thx :)

by Hal on Monday, May 18th 2009 at 01:09 PM

I would also like a copy. hdirector @ cox dot net

Thanks

by Hal on Monday, May 18th 2009 at 01:09 PM

I would also like a copy. hdirector @ cox dot net

Thanks

by megaupload on Tuesday, May 19th 2009 at 01:50 AM

please, put copy in megaupload for all people !!!

Thanks in advance, mister master

by Lee on Sunday, June 28th 2009 at 03:34 PM

i am receiving an error when I close the form...

Cannot access a disposed object.
Object name: \'Form1\'.


this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize1 });

by espinete on Monday, June 29th 2009 at 12:58 AM

Where is mister Rickey, please ?? Thanks.

by Rickey on Wednesday, July 1st 2009 at 02:33 PM

http://www.diamonddrake.com/DownloadEX/DownLoadThis.zip

Here is the example project. its in VS2008 format. if you have an earlier version. just load up the .cs files manually.

It works great.
Enjoy it and learn.

by Lee on Sunday, July 12th 2009 at 02:44 PM

Rickey thanks for the program. I have one issue though, clicking Cancel doesn't stop the download. Any idea how to fix this?

by dil on Tuesday, July 14th 2009 at 02:11 PM

Hi very helpful content!
but i am in trouble!
can anyone help me to fix the problem
"I can get only login page"
I used credentials and cookies

Thanks

by adam on Thursday, September 10th 2009 at 08:25 AM

how do you get it to resume a download even after the app has been closed?

by Admin on Tuesday, October 20th 2009 at 09:28 PM

Good

by Pooja on Thursday, December 17th 2009 at 03:18 AM

Plz....how the window of download manager will pop up instead of default download window?? To write the code for this can we edit systems call or any other technique used? Plz provide me appropriate source code..
Thank you


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs C# Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Latest Tech Bargains

Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons