I'm brand new to coding with c# so can someone tell me how I can include code into this to show the progress bar of file downloading?
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
MessageBox.Show("File will start downloading");
var path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
client.DownloadFile("GOOGLE DRIVE LINK", path);
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
}
To update a progress bar while your WebClient downloads data you have to use a function that does this task in the background. WebClient has a useful function called DownloadFileAsync. This function does exactly that: It downloads in the background.
The code so with this change:
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
MessageBox.Show("File will start downloading");
var path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
}
Unfortunately we have a problem now. The method starts the download in the background and your code immediately continues. This means you press your button, the first MessageBox pops up, the second MessageBox pops up right after the first one and if your download isn't completed when you close the second one your file is executed too early.
To avoid this WebClient has events. The one we need is called DownloadFileCompleted. As the name suggests it executes whatever you want when the download is completed. So let's look at the new code:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe"); // We need our path to be global
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
Our next problem: client is inside a using block. This is great for foreground downloads but if we do it asynchronously (that's what doing it in the background is called) your client will be dead as soon as the block is left which is immediately after the download has been started. So let's make our client global to be able to destroy it later on.
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client; // Here it is!
private void button4_Click(object sender, EventArgs e)
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
Now let's assume the user can press the button a second time before the download is completed. Our client would be overwritten then and the download would be canceled. So let's just ignore the button press if we're already downloading something and only create the new client if we don't have one. New code:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client;
private void button4_Click(object sender, EventArgs e)
{
if (client != null && client.IsBusy) // If the client is already downloading something we don't start a new download
return;
if (client == null) // We only create a new client if we don't already have one
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
}
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
Now that the boring part is done let's come to your problem: Viewing the progress in a progress bar. WebClient has got another event called DownloadProgressChanged. We can use it to update our progress bar.
Talking about progress bars: In Windows Forms you can create one by searching for ProgressBar in the tool bow window in Visual Studio. Then place it somewhere in your window. The ProgressBar component has a few properties which are important for its range. We're lucky, the default values are exactly what we need.
Our updated code (assuming your progress bar is called progressBar1:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client;
private void button4_Click(object sender, EventArgs e)
{
if (client != null && client.IsBusy) // If the client is already downloading something we don't start a new download
return;
if (client == null) // We only create a new client if we don't already have one
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted;
client.DownloadProgressChanged += client_DownloadProgressChanged; // Add new event handler for updating the progress bar
}
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) // NEW
{
progressBar1.Value = e.ProgressPercentage;
}
Notes:
You can create the FormClosing method by double clicking the FormClosing event in your window's property box.
Calling client.Dispose() is only necessary when your program doesn't exit after closing the window. In any other case you could get rid of the FormClosing stuff completely.
That's all finally. I hope this wasn't too long for you and I could help you. Feel free to ask for clarification. That's what comments are there for.
Related
I am downloading a file from web using web client. You can find my code below.
`
private void downloadFile()
{
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string autoDir = desktopPath + "\\npp.8.4.7.Installer.x64.exe";
// This will download a large image from the web, you can change the value
// i.e a textbox : textBox1.Text
string url = $"https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.4.7/npp.8.4.7.Installer.x64.exe";
using (wc)
{
wc.DownloadProgressChanged += Wc_DownloadProgressChanged;
wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
wc.DownloadFileAsync(new Uri(url), autoDir);
}
}
private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
progressBar.Value = 0;
if (e.Cancelled)
{
MessageBox.Show("The download has been cancelled");
this.Close();
return;
}
if(!e.Cancelled)
{
this.Close();
}
if (e.Error != null) // We have an error! Retry a few times, then abort.
{
MessageBox.Show("An error ocurred while trying to download file");
return;
}
}
private void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
percentageText.Text = (e.ProgressPercentage).ToString()+" %";
Console.WriteLine("Downloading..." + e.ProgressPercentage);
}
private void cancel_Click(object sender, RoutedEventArgs e)
{
wc.CancelAsync();
wc.Dispose();
}
`
When I do Cancel while downloading a file, it's not aborting a downloading process. Even After done a cancellation, My code processing with Wc_DownloadProgressChanged Event. Then my file getting download in my directory.
If I Cancel the downloading, The downloading process should be stop and If it is any partially downloaded file existing in my local directory that should be deleted.
please help me out for this.
I have this C# code that does not do the job. This code should run a code when the download is complete. But it does not work.
Code:
private void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
ZipFile.ExtractToDirectory("web/data/main/web.zip", "web/");
}
private void flatToggle2_CheckedChanged(object sender)
{
if (flatToggle2.Checked)
{
//Create File
Directory.CreateDirectory("web/data/main/");
timer2.Start();
bunifuProgressBar1.Show();
bunifuCustomLabel1.Show();
//Downloand
using (var client = new WebClient())
{
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadFileCompleted);
client.DownloadFile("https://www.apachelounge.com/download/VC15/binaries/httpd-2.4.29-Win64-VC15.zip", "web/data/main/web.zip");
}
}
else
{
}
}
This is the code that does not work
private void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
ZipFile.ExtractToDirectory("web/data/main/web.zip", "web/");
}
I tried to run this code without the Unzip but it did not work so I need help with this code.
Looking at the documentation, DownloadFile() is synchronous, so there is no callback needed. Try instead just:
using (var client = new WebClient())
{
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadFileCompleted);
client.DownloadFile("https://www.apachelounge.com/download/VC15/binaries/httpd-2.4.29-Win64-VC15.zip", "web/data/main/web.zip");
ZipFile.ExtractToDirectory("web/data/main/web.zip", "web/");
}
This should suffice.
I'm working on a downloader manger to my app but I couldn't know how to make the Stop button work I search for solution but I couldn't find anything can help me
The code is
[c#]
private void btnDownload_Click(object sender, EventArgs e)
{
btnDownload.Enabled = false;
btnStop.Enabled = true;
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync(new Uri(url.Text), path.Text ; )
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Download completed!");
}
private void btnstop (object sender , e)
{
btnDownload.Enabled = true;
btnstop.Enabled = false;
progressbar.value = 0;
}
As Nitro.de says, you should use WebClient.CancelAsync.
Cancels a pending asynchronous operation.
and remember checking if the e.Cancelled is true
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if(e.Cancelled)
MessageBox.Show("Download cancelled!");
else
MessageBox.Show("Download completed!");
}
To cancel a WebClient async request, you can call the WebClient.CancelAsync method as found here. Note that this still calls the download completed handler, so you will have to check if e.Canceled is true in your Completed function before showing the message box.
Well, Im trying to donwload a file from GitHub using WebClient C# Class but I always get the file corrupted.. this is my code
using (var client = new WebClient())
{
client.DownloadFile("https://github.com/trapped/rotmg_svr/archive/master.zip", #"C:/Users/Asus/Desktop/aa.zip");
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
}
static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage.ToString());
}
//////
public static void ReadFile()
{
WebClient client = new WebClient();
client.DownloadFile("https://github.com/trapped/rotmg_svr/archive/master.zip", #"C:/Users/Asus/Desktop/aa.zip");
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);
}
static void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
Console.WriteLine("Finish");
}
static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage);
}
Now Im using that code and calling that function Reader.ReadFile(); , file downloads good but nothing is written in console (e.percentage) .
Thanks
You are calling DownloadFile() before setting up your event handlers. The call to DownloadFile() will block your thread until the file has finished downloading, which means those event handlers will not be attached before your file has already downloaded.
You could switch the order around like so:
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFile("https://github.com/trapped/rotmg_svr/archive/master.zip", #"C:/Users/Asus/Desktop/aa.zip");
or you could use DownloadFileAsync() instead, which will not block your calling thread.
I have another question :(.
I'm trying to download multiple files for my application.
My question is: What do I have to do to check if the first download is done and then continue to the second download and so on?
This is my code atm:
private void DownloadBukkit()
{
MySingleton.Instance.FirstStartProgress = "Downloading Bukkit.jar... Please stand by...";
webClient.DownloadFileAsync(new Uri(MySingleton.Instance.BukkitDownloadLink), Jar_Location);
webClient.DownloadProgressChanged += backgroundWorker1_ProgressChanged;
webClient.DownloadFileCompleted += (webClient_DownloadFileCompleted);
}
private void DownloadDll()
{
if (!webClient.IsBusy)
{
MySingleton.Instance.FirstStartProgress = "Downloading HtmlAgilityPack.dll... Please stand by...";
webClient2.DownloadFileAsync(new Uri(Dll_HtmlAgilityPackUrl), Dll_HtmlAgilityPackLocation);
webClient2.DownloadProgressChanged += backgroundWorker1_ProgressChanged;
webClient2.DownloadFileCompleted += (webClient2_DownloadFileCompleted);
}
}
void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
DownloadDll();
}
void webClient2_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
Invoke((MethodInvoker)
Close);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Invoke((MethodInvoker)
delegate
{
labelProgress.Text = MySingleton.Instance.FirstStartProgress;
progressBar1.Value = e.ProgressPercentage;
});
}
I have checked this link: DownloadFileAsync multiple files using webclient but I didn't really understand how to implant this :(. (I'm quite new to C#)
The DownloadFileCompleted event is your signal to know that you are finished downloading the file.
From MSDN:
This event is raised each time an asynchronous file download operation
completes.
It's not clear from your code, where and how webClient and webClient2 are declared but essentially, you can start your second download when the first DownloadFileCompleted event is fired. Note, however, that you can perform the download of 2 different files concurrently provided you use 2 separate instances of WebClient.
Here is the fast forward code you can change it as per your requirement .
WebClient client = null;
public FileDownloader()
{
InitializeComponent();
client = new WebClient();
client.DownloadProgressChanged += client_DownloadProgressChanged;
client.DownloadFileCompleted += client_DownloadFileCompleted;
}
void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
lblMessage.Text = "File Download Compeleted.";
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
lblMessage.Text = e.ProgressPercentage + " % Downloaded.";
}
private void StartDownload(object sender, RoutedEventArgs e)
{
if (client == null)
client = new WebClient();
//Loop thru your files for eg. file1.dll, file2.dll .......etc.
for (int index = 0; index < 10; index++)
{
//loop on files
client.DownloadFileAsync(
new Uri(
#"http://mywebsite.com/Files/File" + index.ToString() + ".dll"
, UriKind.RelativeOrAbsolute),
#"C:\Temp\file+" + index.ToString() + ".dll");
}
}