How do I make sure that the file I download has finished? - c#

I have this application which allows me to download certain files from the internet when I press a button.
However.. I have no idea how to make sure that the file has actually finished downloading.
I'm currently using the good old WebClient method of downloading files
using (WebClient client = new WebClient())
{
client.DownloadFileAsync(new System.Uri(requestUrl), combinedPaths);
}
There is no need to show more of the code really since the download function is very simple and straight forward.
I need to figure out how to keep track of the file that you are downloading to see how much it has downloaded for example 1 / 100%..
I have a very good ISP with 250 Mb/s download speed so its really hard for me to see if it has actually been finished or not.

You can fire WebClient.DownloadFileCompleted event and do something with it:
client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback);
To know the status of the download you can subscribe to another event handler:
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);

The WebClient has an event handler called DownlaodFileCompleted that you can use to trigger when the file has finished downloading :
myWebClient.DownloadFileCompleted += DownloadCompleted;
public static void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
Console.WriteLine("Success");
}

Related

Update a WinForms-Application automatically (async)

I am trying to write a little application and, as I am only a student, i was wondering if someone maybe could help me with with some advices / tips to achieve the following:
On start, the desired program shall call a special function. That function looks onto a remote server (most likely it will be a NAS - network attached storage - with given username + password) if there is an update available. If yes, download & install it (including a display of the current progress) and restart program afterwards.
Having done some research, I found the following code snippet, hope it helps:
var webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync("https://195.50.139.130:5001/FTP/KlingGastro Update/file.txt", "C:\\file.txt");
Please note there is a blank character between KlingGastro and Update.
Furthermore the credentials are "KlingGastro" as username, please excuse that I will not post password due to security reasons. Lets say its "myPassword".
I think downloading is not going to be that big problem, I already found this tutorial:
https://ourcodeworld.com/articles/read/227/how-to-download-a-webfile-with-csharp-and-show-download-progress-synchronously-and-asynchronously
Rather the cancellation of the program by itself and the restart might could be difficult?
Sorry for all potential language faults in addition, hope it was nevertheless somehow understandable.
Would be really happy for every answer and help effort.
Best regards
A call to "System.Windows.Forms.Application.Restart()" within the DownloadFileCompleted event-handler will do this for you after the update is completed.
Well, You May Need To Clear Your Question A Bit Furthermore. If You Are Wanting Your Program To Cancel The Download Task And Then Restart The Program Again,
webClient.CancelAsync();
System.Diagnostics.Process.Start(Application.ExecutablePath);
System.Diagnostics.Process.GetCurrentProcess().Kill();
else if you are wanting your program to cancel the download task and start download again,
webClient.CancelAsync();
//Initializing A New One So It Can't Cause Any Issues
webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync("https://195.50.139.130:5001/FTP/KlingGastro Update/file.txt", "C:\\file.txt");
Hope It Helps! If It Doesn't Help, Please Let Us Know Exactly What You Are Trying To Achieve.

WebClient DownloadFileCompleted event not being called in the last item

I Have a large file downloader (about 3GB) full working in almost all devices I tested it. But it some devices the download bar allways gets stuck in 99% (cannot verify this, but seems that is something related with old Win 7 versions). The download works fine, and if I restart the downloader, it shows me that the download is OK, but I cannot tell my clients to restart the downloader if it gets stuck in 99%, so I will appreciate a lot some help on this.
This is the code:
using (_wc = new WebClient())
{
_wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
_wc.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
_wc.DownloadFileAsync(new Uri(fileToDownloadLink), PathToSaveFile);
}
And the event:
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("This box is being called every time except the last one");
}

How does .NET know when to continue to the next line of code?

I wrote this little bit of C# code to test an implementation I intend to use for an internal tool at work. Much to my surprise, it functions exactly as I hoped but I do not understand why.
private void button1_Click(object sender, EventArgs e)
{
WebClient wc = new WebClient();
wc.DownloadFile("http://url censored", #"C:\Users\Dustin\Desktop\flashplayer.exe");
bool dlComplete = System.IO.File.Exists(#"C:\Users\Dustin\Desktop\flashplayer.exe");
if (dlComplete == true)
{
System.Diagnostics.Process.Start(#"C:\Users\Dustin\Desktop\flashplayer.exe");
}
else
{
System.Windows.Forms.MessageBox.Show("Something's jacked!");
}
}
When I press on button1, my machine downloads the Flash installer and then checks if the file exists (this is my roundabout way of avoiding event handlers which I have not learned to deal with yet), and continues on.
Why doesn't my computer check for the file's existence while the file is downloading? How does this wizard of a computer know to hold on a moment while the file download completes?
WebClient.DownloadFile is a Synchronous method in which downloads to a local data file.
As stated on the MSDN link here - "[t]his methods blocks while downloading the resource."
In other words, the process is waiting for completion (blocking the calling function), before returning control and execution to the thread.
This results in the wizardry you're experiencing with the application knowing when to check for the file's presence. I know magic can be ruined once you know the trick; however, I hope this ins't the case..
For reference, here's a way that would work the way you didn't expect, asynchronously.
var webClient = new WebClient())
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync("http://www.server.com/file.txt", "C:\\file.txt");
In fact, there's a whole set of Asynchronous C# functions. It's worth reading up on if you're interested in getting into development.
https://msdn.microsoft.com/en-us/library/mt674882.aspx

Pause and resume a download WPF

Hello I am working on a WPF platform targeting .NET framework 4.5.2. I am writing a downloader for my application. Here is the code:
private void Download(Dictionary<int, FileAndLinkClass> MyLinks)
{
ApplicationDownloadThread = new Thread(() =>
{
foreach (KeyValuePair<int, FileAndLinkClass> item in MyLinks)
{
fileNo++;
WebClient myWebClient = new WebClient();
myWebClient.DownloadProgressChanged += MyWebClient_DownloadProgressChanged;
myWebClient.DownloadFileCompleted += MyWebClient_DownloadFileCompleted;
// Download the Web resource and save it into the current filesystem folder.
string downloadedFileAdress = System.IO.Path.Combine(fileLocation, $"{item.Value.FileName}");
myWebClient.DownloadFileAsync(new Uri(item.Value.Link), downloadedFileAdress);
while (myWebClient.IsBusy)
{
}
}
});
ApplicationDownloadThread.IsBackground = false;
ApplicationDownloadThread.Start();
//UnZipAndCreateUpdatePackage(MyLinks);
}
Now I want at button click the download must be paused and at another button click the download must be resumed. I tried working with .set() property of an AutoReset event and .Reset() property of the same but it didn't work.
I need help. My button click code are:
private AutoResetEvent waitHandle = new AutoResetEvent(true);
private void StartDownloadBtn_Click(object sender, RoutedEventArgs e)
{
waitHandle.Set();
}
private void StopDownloadBtn_Click(object sender, RoutedEventArgs e)
{
waitHandle.Reset();
}
I have also tried this link How to pause/suspend a thread then continue it?. nothing happens
I've also gone through Adding pause and continue ability in my downloader but I failed to incorporate the solution in my above code as I am also updating the download progress on the UI.
Well I did some more digging, apparently if for you Adding pause and continue ability in my downloader wasn't clear as the it uses byte stream data in the class. Maybe you could check out the link below, it also provides a VS solution on WPF for the downloading .zip file extensions with pause/resume/stop capabilities. Please let me know if you need some more help.
Link to CodeProject article:
C# .NET Background File Downloader

ASP.NET FileSystemWatcher Changed Event

I created a ASP.NET Website with Visual Studio 2010 C#.
My program reads a config file to create some classes and display informations.
The config file is not included in the project (does not appear in the solution explorer). If I modify the file while my application is not running, and run it afterwards, it still reads the old version like it keep it in cache. I have to close Visual Studio for it to accept the changes.
My second problem is related to (if not caused by) my first problem. I am using FileSystemWatcher to see if the config file is modified while the application is running, but the Changed event is never called.
private string _configFilePath;
private FileSystemWatcher _watcher;
protected void Page_Load(object sender, EventArgs e)
{
//Gets the config file in the application's parent directory
string appPath = this.MapPath("~");
string[] split = appPath.Split('\\');
_configFilePath = appPath.Substring(0, appPath.Length - split[split.Length-1].Length);
Application.Add("watcher", new FileSystemWatcher(_configFilePath.Substring(0, _configFilePath.Length-1), "*.xml"));
_watcher = (FileSystemWatcher)Application["watcher"];
_watcher.NotifyFilter = NotifyFilters.FileName;
_watcher.Changed += new System.IO.FileSystemEventHandler(Watcher_Changed);
_configFilePath += "ProductsConfig.xml";
UpdateDisplay();
}
private void Watcher_Changed(object source, FileSystemEventArgs e)
{
UpdateDisplay();
}
How can I solve this?
Thank you
My second problem is related to (if not caused by) my first problem. I
am using FileSystemWatcher to see if the config file is modified while
the application is running, but the Changed event is never called.
It's never called because at that point the Thread that's servicing the request is already returned to the pool and the request has ended. The Watcher_Changed event will never fire.
You need to tackle this in a different manner, remember that HTTP is a "disconnected" protocol, after the request has been served, don't expect any of the page events to fire "automagically" when something happens on the server side that would notify all connected users.
One way to do this is via Ajax. You'd need to constantly "ask" the server whether there's new information or not and update the sections of the page that need to be updated as a result of the change on the server.
There are 2 problems here.
1. You never called _watcher.EnableRaisingEvents = true;
2. You try to go to the parent folder of your root folder, which might not be allowed.
/ Tibi

Categories

Resources