I am working on an application that will download a .zip file from my server and extract it when the download is complete using DotNetZip 1.9
The application is downloading the zip file properly, but when it gets to the section to read the .zip file it throws the exception "Cannot read that as a zip file" (full exception at http://pastebin.com/NTrtMgR9).
What throws me off, is even tho it is throwing an exception, the file is still unzipped properly...
Here is my source:
private void btnDownload_Click(object sender, EventArgs e)
{
if (!Directory.Exists(HardCorpsPath))
{
//MessageBox.Show("Downloading HardCorps Mod Pack (Full)", "Downloading", MessageBoxButtons.OK, MessageBoxIcon.Information);
zipFileName = "HardCorps";
HCDownloadURL = String.Format("http://www.survivaloperations.net/client/hardcorps/{0}.zip", zipFileName);
HCZipPath = Path.Combine(Arma2OAPath, #"HardCorps.zip");
WebClient Download_Client = new WebClient();//Declaring the webclient as Download_Client
Download_Client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);//the event handler
Download_Client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);// " "
Download_Client.DownloadFileAsync(new Uri(HCDownloadURL.Trim().ToString()), HCZipPath);// " "
//extract
using (var zipFile = ZipFile.Read(HCZipPath))
{
zipFile.ExtractAll(Arma2OAPath, ExtractExistingFileAction.OverwriteSilently);
}
}
else
{
MessageBox.Show("Directory Validated!");
//Read users HardCorpsPath\version.txt and compare to server version.txt
//if server version > user version, download patch.zip where "patch" == the number version of the server's version.txt (ex: 1001.zip)
//On download complete, extract to HardCorpsPath and overwrite silently
}
}//close Download Button
and my ProgressChanged/Completed methods:
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
pbDownloader.Value = e.ProgressPercentage;//setting the progressbar value as downloadprogress
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
using (var zipFile = ZipFile.Read(String.Format(HCZipPath)))
{
zipFile.ExtractAll(Arma2OAPath, ExtractExistingFileAction.OverwriteSilently);
}
MessageBox.Show("Downloading Successful ", "Download_Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);//just a messagebox
pbDownloader.Value = (0);//resetting the progressbar
}
HCZipPath is a string variable (if that makes any difference)
In your btnDownload_Click method, you are trying to extract the file before it has been downloaded. You call Download_Client.DownloadFileAsync which starts the download, and you've correctly set up the handler for the DownloadFileCompleted event where you try to do the extraction (again). Take out the code below the DownloadFileAsync method call (to prevent the exception). You file is being extracted because you extract it in the Completed method (which is the correct way to do it).
Related
I don't have any knowledge about C# but I need to create an FTP server that automatically download a list of files (one by one, from the last to the first), so I downloaded some source codes of FTP servers and the most functional I found have a little problem, my task is to get a server that download files automatically, but the code I get open an window to select where to save the file.
How can i change it to download the files automatically?
(If possible, explain throughly how your code work, it will help me to better understand and learn C#)
private void ServerFileListView_DockChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in ServerFileListView.Items)
{
item.Selected = true;
}
byte[] file;
Server.Download(MachineInfo.GetJustIP(), ServerFileListView.SelectedItems[0].SubItems[2].Text, out file);
SaveFileDialog save = new SaveFileDialog();
save.Title = "It saves the downloaded file.";
save.SupportMultiDottedExtensions = false;
save.Filter = "*.png|*.png";
save.FileName = ServerFileListView.SelectedItems[0].SubItems[2].Text;
if (save.ShowDialog() != System.Windows.Forms.DialogResult.Cancel)
{
System.IO.File.WriteAllBytes(save.FileName, file);
MessageBox.Show(ServerFileListView.SelectedItems[0].SubItems[2].Text +" has been downloaded.", "FTP File Sharing", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
save.Dispose();
}
If you want more details ask in the comments.
(Sorry for bad speech, i'm not fluently in english)
You need to remove the SaveFileDialog() it is meant to save file interactively.
Get the list of the file and put in array
and loop (foreach) the array to run the download method
better yet, run the method in a separate thread or async, so it will not block the main thread.
Pseudo:
{run in thread
if(ftp is connected)
{
connect;
string listToDownload[] = getListFileFromServer;
foreach (var item from listToDownload)
{file = getFileFromServer;
saveToDisk(file);
}
}
}
In the top of form1 i did
WebBrowser webbrowser1;
Then in the constructor
webbrowser1 = new WebBrowser(); webbrowser1.Navigate("http://www.ims.gov.il/IMS/tazpiot/RainRadar.htm");
webbrowser1.DocumentCompleted += webbrowser1_DocumentCompleted;
Then in the DocumentCompleted event
void webbrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsoluteUri != webbrowser1.Url.AbsoluteUri)
{
return;
}
IHTMLDocument2 doc = (IHTMLDocument2)webbrowser1.Document.DomDocument;
IHTMLControlRange imgRange = (IHTMLControlRange)((HTMLBody)doc.body).createControlRange();
foreach (IHTMLImgElement img in doc.images)
{
imgRange.add((IHTMLControlElement)img);
imgRange.execCommand("Copy", false, null);
using (Bitmap bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap))
{
bmp.Save(#"E:\newimages\" + img.nameProp);
}
}
}
I'm getting on the hard disk 20 images saved.
But not the one i needed. The one i need to save from this page in the webBrowser is the image in this link: http://www.ims.gov.il/Ims/Pages/RadarImage.aspx?Row=9&TotalImages=10&LangID=1&Location=
The radar it self image. I can make save as...
And i can use like i'm doing today WebClient...
But WebClient is not working all the time. So i'm trying to surf to the site and get the image of the radar from the webBrowser. But without success.
UPDATE
This is my webclient how i'm downloading the radar image today:
private void fileDownloadRadar()
{
if (Client.IsBusy == true)
{
Client.CancelAsync();
}
else
{
try
{
Client.DownloadFileAsync(myUri, Path.Combine(combinedTemp));
}
catch(Exception errors)
{
string errors2 = errors.ToString();
}
}
}
Client is WebClient
Now i'm going to the directory of where it was downloaded combinedTemp and i see that the downloaded file is 0kb empty.
The url in myUri is:
http://www.ims.gov.il/Ims/Pages/RadarImage.aspx?Row=9&TotalImages=10&LangID=1&Location=
When i put this link in my chrome and surf to it i see the latest radar image but when i'm looking in my hard disk it's 0kb the downloaded file.
And i will add this is not happening now but some time ago some months ago i had another problem in some cases not all the time but in many times when i downloaded the image i had another error i even have open question about it one year ago : Why i'm getting exception: Too many automatic redirections were attempted on webclient?
So in general it's two problems but now the problem is that the downloaded file is 0kb.
This is the Client completed event:
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
try
{
client_Error_counter = client_Error_counter + 1;
if (client_Error_counter == 5)
{
Logger.Write("Tried to download radar image file " + client_Error_counter + " times without success");
Logger.Write("Error Tried to download radar image file : " + e.Error);
client_Error_counter = 0;
}
else
{
Client.DownloadFileAsync(myUri, Path.Combine(combinedTemp));
Logger.Write("Times tried to download radar image file: " + client_Error_counter);
Logger.Write("Error Tried to download radar image file : " + e.Error);
}
}
catch(Exception errors)
{
string myerr = errors.ToString();
}
}
And i see now i missed it that when it's getting to the DownloadFileCompleted event there is an error:
e.Error show: e.Error = {"Too many automatic redirections were attempted."}
StackTRace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)
This is why i tried to use the WebBrowser. I can't find a way to solve this "Too many automatic redirections were attempted" problem.
That's why i see the file 0kb on my hard disk.
Another thing is today few hours ago it did download fine some radar images but now it's making this error again.
I have several issues within a windows forms application. So far, I have managed to loop though a folder and display the reuslts in a text box. Once these have returned, the user can check the results and the error files can be removed using the following;
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
File.Delete(file);
}
}
What I want to do now, after the error files have been removed, is copy the same files from a backup folder (the only difference in the filenames is the file extention) I am using a seperate button for this action. Any help on this final step would be greatly appreciated.
Use Path class to get File names without extensions, combine paths and more, as an example:
StringCollection filesToBeReplaced = new StringCollection();
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
//Now you have file names without extension
filesToBeReplaced.Add(Path.GetFileNameWithoutExtension (file));
File.Delete(file);
}
}
private void CopyGoodFilesFromSource()
{
foreach(string fileName in filesToBeReplaced)
{
string sourceFilePath = Path.Combine("YOUR FOLDER FOR GOOD FILES",
Path.ChangeExtension(fileName,"Your Extension")) ;
string destinationPath = Path.Combine("Destination Folder",
Path.ChangeExtension(fileName, "Your Extension in destination folder");
File.Copy(sourceFilePath , destinationPath, true);
}
}
I have been trying to link a TextBox to an external text file in a Visual Studio 2012 Windows 8 store app and eventually be able to edit the contents of this TextBox afterwards with a SAVE button, but unfortunately i get the error which is shown in the link of the screenshot. I am running Windows 8 on a virtual machine !
[1]: http://i.imgur.com/gQWlIm4.png "ERROR
[2]: http://i.imgur.com/hHj9vXx.png "Place of the error in the designer page
COde that i am using for filling the TextBox:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
LoadWords(#"Assets\AdminPageKS1words.txt");
}
async private void LoadWords(string filename)
{
var wordList = new List<String>();
// this method reads line separated words from a text file and populates a List object //
Windows.Storage.StorageFolder localFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// begin the file read operation
try
{
// open and read in the word list into an object called words
StorageFile sampleFile = await localFolder.GetFileAsync(filename);
var words = await FileIO.ReadLinesAsync(sampleFile);
// add each word returned to a list of words declared
// globally as List wordList = new List();
foreach (var word in words)
{
wordList.Add(word);
}
List1.Text = string.Join(Environment.NewLine, wordList);
}
catch (Exception)
{
// handle any errors with reading the file
}
Code that i am using for the SAVE button:
async private void SaveButton_Click(object sender, RoutedEventArgs e)
{
// locate the local storage folder on the device
Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
// create a new text file in the local folder called “File.txt”
StorageFile sampleFile = await localFolder.CreateFileAsync("File.txt",CreationCollisionOption.ReplaceExisting);
// write text to the file just created – text comes from a textblock called wordlistBox
await FileIO.WriteTextAsync(sampleFile, List1.Text);
// display a message saying that file is saved.
messageLabel.Text = keystage + "File saved";
}
public string keystage { get; set; }
The code works for me, but you have a Try..Catch block which is effectively ignoring any exceptions. I'd suggest one of the following:
- Add a breakpoint to the start of Page_Loaded to check that it's actually being called, then step through the code to see whether there's an exception.
- Modify your Catch Block to write out the error information:
catch (Exception ex)
{
messageLabel.Text = ex.Message;
}
I'm trying to download zend-framework (from http://framework.zend.com/releases/ZendFramework-1.11.11/ZendFramework-1.11.11.zip) simply using WebClient
string url = "http://framework.zend.com/releases/ZendFramework-1.11.11/ZendFramework-1.11.11.zip";
WebClient downloader= new WebClient();
downloader.DownloadFileAsync(new Uri(url), "C:\\temp.zip");
The file is created, but it is empty. I checked response using fiddler and I get HTTP 200, correct content-length but "connection: closed" and fiddler shows "-1" in "body" column.
I have tried adding user agent (copied from google chrome request) and "connection: keep-alive" to headers, but none of these helped. I'm also pretty sure, that my program downloaded this file using the same URL once or twice before. There are no errors in events fired by WebClient.
Any ideas?
Ok, I finnaly found the answer! Before downloading the file, I was checking its size by sending HttpWebRequest. The problem was, that i didn't Close() the response.
Thanks for the answers, they were nice clues.
Just my guess: maybe you can try to keep the WebClient instance in some place would not be garbage collected. When the DownloadFileCompleted event fired, you just clean the reference to the WebClient instance and let GC to reclaim the memory later (and don't forget to call Dispose method).
Try to handle the DownloadProgressChanged and DownloadFileCompleted event.
private void button1_Click(object sender, EventArgs e)
{
string url = "http://framework.zend.com/releases/ZendFramework-1.11.11/ZendFramework-1.11.11.zip";
WebClient downloader = new WebClient();
downloader.DownloadFileCompleted += new AsyncCompletedEventHandler(downloader_DownloadFileCompleted);
downloader.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloader_DownloadProgressChanged);
downloader.DownloadFileAsync(new Uri(url), "C:\\temp.zip");
}
void downloader_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
label1.Text = e.BytesReceived + " " + e.ProgressPercentage;
}
void downloader_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(e.Error.Message);
else
MessageBox.Show("Completed!!!");
}
If you have UAC enabled in Windows "C:\temp.zip" in the following line will fail to save the file because you aren't allowed to write outside of user directories without elevated permissions:
downloader.DownloadFileAsync(new Uri(url), "C:\\temp.zip");