A step by step tutorial teaching you how to create your own chat client and chat server easily in C#, for local networks or the Internet.
A C# tutorial showing you how to make use of WMI to extract information on disk drives, such as model, capacity, sectors and serial number.
This tutorial will teach you how to calculate the shipping cost based on the weight, height, length and depth of the box, the distance and the UPS service type.
Creating a Rich Text Editor using JavaScript is easier to do than you might think, thanks to the support of modern browsers; this tutorial will walk you through it.
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 41 votes) |
||
|
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.
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 { 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.
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 It!
Del.icio.us
Reddit
StumbleIt
Newsvine
Furl
BlinkList
|
|||
|
|||
Current CommentsExcellent, 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?
How would I enable this to report the kbps?
--
Great work so far.
--
b
So why don\'t you use the background worker or a Command Pattern?
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
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.
Great work!
Please post an article for the following
Multiple file download at once.
Thank You.
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--
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
how can pass the download when server down
how can i restart when server up
pls reply soon
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.
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.....
I'm interested in part 3!
can u add tutorial about website filter? I really want to learn that.
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.
How can I download a single file with multiple threads in chunks?
hi, what about if the server does not support resume???
by!
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.
Thanks for pointing that out, Tom. That's an interesting limitation that the HttpWebRequest object has, I'll look into it.
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
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 !
To the last guy who commented - that has been mentioned in the tutorial. Did you actually read the tutorial?
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.
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);
}
}
}
}
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 });
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
Please show the third part.
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
Hi,
Would you have this DownloadManager in VB.NET?
Thank you.
Best Regards.
In some cases the webserver returns -1 for ContentLength.
Int64 fileSize = webResponse.ContentLength
fileSize is -1
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.
Thank you Andrew, this is exactly what I need
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!
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
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
get the filesize first n then calculate segments.....
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).
This is interesting...
Please continue the 3rd part....
I'm waiting...
multithread is challenging....i really want to learn it
I am also interested in part 3 of this tutorial.
Regards,
Hal
Very interesting!!
Looking forward for the 3rd part.
Regards. Fon.
Oh, yeah !! 3rd part, please !! for God !!!
thanks
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.
please mister Rickey, Irequest for a copy
thanks
send me, please, anonimoatacante AT yahoo DOT es
at = @
dot = .
I want the copy to mr. Rickey. d.n.a.core@gmailDOTcom thx :)
I would also like a copy. hdirector @ cox dot net
Thanks
I would also like a copy. hdirector @ cox dot net
Thanks
please, put copy in megaupload for all people !!!
Thanks in advance, mister master
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 });
Where is mister Rickey, please ?? Thanks.
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.
Rickey thanks for the program. I have one issue though, clicking Cancel doesn't stop the download. Any idea how to fix this?
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
how do you get it to resume a download even after the app has been closed?
Good
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
A tutorial on how to make a multi file downloader with download list would be awesome. I am looking for something like this for an automatic updating feature for a few programs.
I'm having the same problem Scott mentioned a while back; whilst downloading large files (in my case 142Mb), the download will occasionally freeze and not do anything; giving no errors, warnings or exceptions. Also when trying to exit the app during a hang the window will close but the app will remain running in TaskMan and I have to kill it manually. The odd thing is that this doesn't happen all the time, I would guess that around 1/3 downloads will freeze whilst the rest will download without a problem. Does anyone have any ideas how to fix this?
Ash I'd a simular problem and figured out that this is a ASP issue for files greater than 100MB. You can fix it using a download handler and download multi part.
Related Tutorials
Related Source Code
C# Job Search