I'll try to download file using this code.But file size is 0 KB.What is the correct and efficiency way to download the file.
private void DownloadFile()
{
using (WebClient Client = new WebClient())
{
Client.DownloadFileAsync(
new Uri("http://localhost/sn/userSelect.Designer.cs", UriKind.Absolute),
#"C:\xampp\htdocs\sn\test1.txt");
Client.Dispose();
}
}
Any one can give me the method for download the file over windows form program in C#.thanks
class Program
{
private static WebClient wc = new WebClient();
private static ManualResetEvent handle = new ManualResetEvent(true);
private static void Main(string[] args)
{
wc.DownloadProgressChanged += WcOnDownloadProgressChanged;
wc.DownloadFileCompleted += WcOnDownloadFileCompleted;
wc.DownloadFileAsync(new Uri(#"http://www.nattyware.com/bin/pixie.exe"), #"C:\\pixie.exe");
handle.WaitOne(); // wait for the async event to complete
}
private static void WcOnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (!e.Cancelled && e.Error == null)
{
//async download completed successfully
}
handle.Set(); // in both the case let the void main() know that async event had finished so that i can quit
}
private static void WcOnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// handle the progres in case of async
//e.ProgressPercentage
}
Related
Description:
So I have this following script to download a file from the internet with a progress bar showing what percentage the download is at and custom message boxes. Now I have the files being saved to the users %TEMP% path. And it uses events to prevent people from clicking on the button again and starting a new download.
Problem:
I want to give the user a choice of where to save the file, but show his temp path as the default location. (Like a Save-file-dialog Box)
I'm still fairly new to coding and don't know where to exactly start.
What I tried:
I didn't try any new code, but I did go around google and try to find a solution. Here are some websites that I found that might be useful:
https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-save-files-using-the-savefiledialog-component
https://www.c-sharpcorner.com/UploadFile/mahesh/savefiledialog-in-C-Sharp/
They explain it really well. But I don't know how to incorporate it into this script.
And I dont want to write a brand new script. Any Help would be Appreciated!
private bool _isBusy = false;
private void button1_Click(object sender, EventArgs e)
=> DownloadFile("someurl1", "somefilename1.exe");
private void button2_Click(object sender, EventArgs e)
=> DownloadFile("someurl2", "somefilename2.exe");
private void button3_Click(object sender, EventArgs e)
=> DownloadFile("someurl3", "somefilename3.exe");
private void button4_Click(object sender, EventArgs e)
=> DownloadFile("someurl4", "somefilename4.exe");
private void DownloadFile(string url, string fileName)
{
if(_isBusy) return;
_isBusy = true;
var output = Path.Combine(Path.GetTempPath(), fileName);
MessageBox.Show($"{fileName} will start downloading from {url}");
using (WebClient client = new WebClient())
{
client.DownloadFileCompleted += (sender, args) =>
{
MessageBox.Show($"{fileName} Complete!");
Process.Start(output);
_isBusy = false;
};
client.DownloadProgressChanged += (sender, args) => progressBar1.Value = args.ProgressPercentage;
client.DownloadFileAsync(new Uri(url), output);
}
}
Maybe something like?
private SaveFileDialog save = new SaveFileDialog();
private void DownloadFile(string url, string fileName)
{
if (_isBusy) return;
save.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
save.FileName = fileName;
if (save.ShowDialog() == DialogResult.OK)
{
_isBusy = true;
var output = save.FileName;
MessageBox.Show($"{fileName} will start downloading from {url}");
using (WebClient client = new WebClient())
{
client.DownloadFileCompleted += (sender, args) =>
{
MessageBox.Show($"{fileName} Complete!");
Process.Start(output);
_isBusy = false;
};
client.DownloadProgressChanged += (sender, args) => progressBar1.Value = args.ProgressPercentage;
client.DownloadFileAsync(new Uri(url), output);
}
}
}
I have a background worker (as seen below) with DownloadFileCompleted/DownloadProgressChanged events. After several hours of testing and a lot of research, I couldn't get it to work. The file downloads successfully but the events don't run. I looked at a lot of documentation pages and searched for this issue here, but they don't seem to match my case... Would appreciate if someone could help me out on this one!
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler (webClient_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler (webClient_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(myUri), path);
}
}
void webClient_DownloadFileCompleted(object s, AsyncCompletedEventArgs e)
{
Debug.WriteLine("Download completed!");
}
void webClient_DownloadProgressChanged(object s, DownloadProgressChangedEventArgs e)
{
Debug.WriteLine(e.BytesReceived);
}
There must be something else wrong with your code as running effectively that same code, it works fine.
Are you sure your program is simply not finished and closing before the work is done as a BackgroundWorker won't keep your application alive.
Here is my example, with a foreground Thread to keep the application alive until done
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
new Thread(() =>
{
var client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
client.DownloadFileAsync(new Uri("https://speed.hetzner.de/100MB.bin"), #"C:\Users\Luke\Desktop\100mb.bin");
}).Start();
}
private static void webClient_DownloadFileCompleted(object s, AsyncCompletedEventArgs e)
{
Debug.WriteLine("Download completed!");
}
private static void webClient_DownloadProgressChanged(object s, DownloadProgressChangedEventArgs e)
{
Debug.WriteLine(e.BytesReceived);
}
}
}
im using the following code to download 50+ files from my webserver
private void button5_Click(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
//downloads
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), #"c:\app\loc ");
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), #"c:\app\loc ");
client.DownloadFileAsync(new Uri("http://www.site.com/file/loc.file"), #"c:\app\loc ");
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
progressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
}
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Game Update Finished!");
}
im wanting to download 1 file at a time with a continuing progress bar iv got most of the coding done but when i hit the "Download" button i get the following error
WebClient does not support concurrent I/O operations.
what do i need to do?
Feel the difference:
It CAN download multiple files in parallel manner (by one stream per
one file).
But it CAN'T download one file using multiple streams.
Here is example (MainWindow contain one button 'Start' and five progress bars):
public partial class MainWindow : Window
{
private WebClient _webClient;
private ProgressBar[] _progressBars;
private int _index = 0;
public MainWindow()
{
InitializeComponent();
_progressBars = new [] {progressBar1, progressBar2, progressBar3, progressBar4, progressBar5};
ServicePointManager.DefaultConnectionLimit = 5;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Interlocked.Increment(ref _index);
if (_index > _progressBars.Length)
return;
_webClient = new WebClient();
_webClient.DownloadProgressChanged += WebClient_DownloadProgressChanged;
_webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;
_webClient.DownloadFileAsync(new Uri("http://download.thinkbroadband.com/5MB.zip"),
System.IO.Path.GetTempFileName(),
_index);
}
private void WebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs args)
{
var index = (int) args.UserState;
_progressBars[index-1].Value = args.ProgressPercentage;
}
private void WebClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs args)
{
var index = (int)args.UserState;
MessageBox.Show(args.Error == null
? string.Format("Download #{0} completed!", index)
: string.Format("Download #{0} error!\n\n{1}", index, args.Error));
}
}
you are running multiple downloads in parallel with the same WebClient instance - the error tells you that this is NOT supported - you either:
use multiple instances of WebClient (one per parallel download)
OR
download one file after the other
Relevant information:
http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx
http://msdn.microsoft.com/en-us/magazine/cc700359.aspx
WebClient does not support concurrent I/O operations (multiple downloads) per instance, so you need to create a separate WebClient instance for each download. You can still perform each download asynchronously and use the same event handlers.
public string[] SearchForMovie(string SearchParameter)
{
WebClientX.DownloadDataCompleted += new
DownloadDataCompletedEventHandler(WebClientX_DownloadDataCompleted);
WebClientX.DownloadDataAsync(new Uri(
"http://www.imdb.com/find?s=all&q=ironman+&x=0&y=0"));
string sitesearchSource = Encoding.ASCII.GetString(Buffer);
}
void WebClientX_DownloadDataCompleted(object sender,
DownloadDataCompletedEventArgs e)
{
Buffer = e.Result;
throw new NotImplementedException();
}
I get this exception:
The matrix cannot be null. Refering to my byte[] variable Buffer.
So, I can conclude that the DownloadDataAsync isn't really downloading anything. What is causing this problem?
PS. How can I easily format my code so it appear properly indented here. Why can't I just copy past the code from Visual C# express and maintain the indentation here? Thanks! :D
The key word here is "async"; when you call DownloadDataAsync, it only starts the download; it isn't complete yet. You need to process the data in the callback (WebClientX_DownloadDataCompleted).
public string[] SearchForMovie(string SearchParameter)
{
WebClientX.DownloadDataCompleted += WebClientX_DownloadDataCompleted;
WebClientX.DownloadDataAsync(new Uri(uri));
}
void WebClientX_DownloadDataCompleted(object sender,
DownloadDataCompletedEventArgs e)
{
Buffer = e.Result;
string sitesearchSource = Encoding.ASCII.GetString(Buffer);
}
Also - don't assume ASCII; WebClientX.Encoding would be better; or just DownloadStringAsync:
static void Main()
{
var client = new WebClient();
client.DownloadStringCompleted += DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://google.com"));
Console.ReadLine();
}
static void DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
if (e.Error == null && !e.Cancelled)
{
Console.WriteLine(e.Result);
}
}
I am using VSTS 2008 + C# + .Net 3.5 + ASP.Net + IIS 7.0 to develop a Windows Forms application at client side to upload a file, and at server side I receive this file using an aspx file.
I find my client side application will hang after click the button to trigger upload event. Any ideas what is wrong and how to solve? Thanks!
Client side code,
public partial class Form1 : Form
{
private static WebClient client = new WebClient();
private static ManualResetEvent uploadLock = new ManualResetEvent(false);
private static void Upload()
{
try
{
Uri uri = new Uri("http://localhost/Default2.aspx");
String filename = #"C:\Test\1.dat";
client.Headers.Add("UserAgent", "TestAgent");
client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback);
client.UploadFileCompleted += new UploadFileCompletedEventHandler(UploadFileCompleteCallback);
client.UploadFileAsync(uri, "POST", filename);
uploadLock.WaitOne();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace.ToString());
}
}
public static void UploadFileCompleteCallback(object sender, UploadFileCompletedEventArgs e)
{
Console.WriteLine("Completed! ");
uploadLock.Set();
}
private static void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine("{0} uploaded {1} of {2} bytes. {3} % complete...",
(string)e.UserState,
e.BytesSent,
e.TotalBytesToSend,
e.ProgressPercentage);
// Console.WriteLine (e.ProgressPercentage);
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Upload();
}
}
Server side code:
protected void Page_Load(object sender, EventArgs e)
{
string agent = HttpContext.Current.Request.Headers["UserAgent"];
using (FileStream file = new FileStream(#"C:\Test\Agent.txt", FileMode.Append, FileAccess.Write))
{
byte[] buf = Encoding.UTF8.GetBytes(agent);
file.Write(buf, 0, buf.Length);
}
foreach (string f in Request.Files.AllKeys)
{
HttpPostedFile file = Request.Files[f];
file.SaveAs("C:\\Test\\UploadFile.dat");
}
}
you are waiting in the main windows events thread, so your GUI will be frozen.
Try this (using non static methods allows you to use the Control.Invoke method to run callbacks on the windows GUI thread and free this thread in order to redraw)
public partial class Form1 : Form
{
private static WebClient client = new WebClient();
private static ManualResetEvent uploadLock = new ManualResetEvent(false);
private void Upload()
{
try
{
Cursor=Cursors.Wait;
Uri uri = new Uri("http://localhost/Default2.aspx");
String filename = #"C:\Test\1.dat";
client.Headers.Add("UserAgent", "TestAgent");
client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback);
client.UploadFileCompleted += new UploadFileCompletedEventHandler(UploadFileCompleteCallback);
client.UploadFileAsync(uri, "POST", filename);
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace.ToString());
this.Cursor=Cursors.Default;
this.Enabled=false;
}
}
public void UploadFileCompleteCallback(object sender, UploadFileCompletedEventArgs e)
{
// this callback will be invoked by the async upload handler on a ThreadPool thread, so we cannot touch anything GUI-related. For this we have to switch to the GUI thread using control.BeginInvoke
if(this.InvokeRequired)
{
// so this is called in the main GUI thread
this.BeginInvoke(new UploadFileCompletedEventHandler(UploadFileCompleteCallback); // beginInvoke frees up the threadpool thread faster. Invoke would wait for completion of the callback before returning.
}
else
{
Cursor=Cursors.Default;
this.enabled=true;
MessageBox.Show(this,"Upload done","Done");
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Upload();
}
}
}
And do the same thing in your progress (you could update a progressbar indicator for example).
Cheers,
Florian