/***************************************************************** * Copyright (C) Knights Warrior Corporation. All rights reserved. * * Author: Ê¥µîÆïÊ¿£¨Knights Warrior£© * Email: KnightsWarrior@msn.com * Website: http://www.cnblogs.com/KnightsWarrior/ https://github.com/knightswarrior * Create Date: 5/8/2010 * Usage: * * RevisionHistory * Date Author Description * *****************************************************************/ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; using System.Net; using System.IO; using System.Diagnostics; using System.Xml; namespace KnightsWarriorAutoupdater { public partial class DownloadProgress : Form { #region The private fields private bool isFinished = false; private List downloadFileList = null; private List allFileList = null; private ManualResetEvent evtDownload = null; private ManualResetEvent evtPerDonwload = null; private WebClient clientDownload = null; #endregion #region The constructor of DownloadProgress public DownloadProgress(List downloadFileListTemp) { InitializeComponent(); this.downloadFileList = downloadFileListTemp; allFileList = new List(); foreach (DownloadFileInfo file in downloadFileListTemp) { allFileList.Add(file); } } #endregion #region The method and event private void OnFormClosing(object sender, FormClosingEventArgs e) { if (!isFinished && DialogResult.No == MessageBox.Show(ConstFile.CANCELORNOT, ConstFile.MESSAGETITLE, MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { e.Cancel = true; return; } else { if (clientDownload != null) clientDownload.CancelAsync(); evtDownload.Set(); evtPerDonwload.Set(); } } private void OnFormLoad(object sender, EventArgs e) { evtDownload = new ManualResetEvent(true); evtDownload.Reset(); ThreadPool.QueueUserWorkItem(new WaitCallback(this.ProcDownload)); } long total = 0; long nDownloadedTotal = 0; private void ProcDownload(object o) { string tempFolderPath = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME); if (!Directory.Exists(tempFolderPath)) { Directory.CreateDirectory(tempFolderPath); } evtPerDonwload = new ManualResetEvent(false); foreach (DownloadFileInfo file in this.downloadFileList) { total += file.Size; } try { while (!evtDownload.WaitOne(0, false)) { if (this.downloadFileList.Count == 0) break; DownloadFileInfo file = this.downloadFileList[0]; //Debug.WriteLine(String.Format("Start Download:{0}", file.FileName)); this.ShowCurrentDownloadFileName(file.FileName); //Download clientDownload = new WebClient(); //Added the function to support proxy clientDownload.Proxy = System.Net.WebProxy.GetDefaultProxy(); clientDownload.Proxy.Credentials = CredentialCache.DefaultCredentials; clientDownload.Credentials = System.Net.CredentialCache.DefaultCredentials; //End added clientDownload.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) => { try { this.SetProcessBar(e.ProgressPercentage, (int)((nDownloadedTotal + e.BytesReceived) * 100 / total)); } catch { //log the error message,you can use the application's log code } }; clientDownload.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => { try { DealWithDownloadErrors(); DownloadFileInfo dfile = e.UserState as DownloadFileInfo; nDownloadedTotal += dfile.Size; this.SetProcessBar(0, (int)(nDownloadedTotal * 100 / total)); evtPerDonwload.Set(); } catch (Exception) { //log the error message,you can use the application's log code } }; evtPerDonwload.Reset(); //Download the folder file string tempFolderPath1 = CommonUnitity.GetFolderUrl(file); if (!string.IsNullOrEmpty(tempFolderPath1)) { tempFolderPath = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME); tempFolderPath += tempFolderPath1; } else { tempFolderPath = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME); } clientDownload.DownloadFileAsync(new Uri(file.DownloadUrl), Path.Combine(tempFolderPath, file.FileFullName), file); //Wait for the download complete evtPerDonwload.WaitOne(); clientDownload.Dispose(); clientDownload = null; //Remove the downloaded files this.downloadFileList.Remove(file); } } catch (Exception) { ShowErrorAndRestartApplication(); //throw; } //When the files have not downloaded,return. if (downloadFileList.Count > 0) { return; } //Test network and deal with errors if there have DealWithDownloadErrors(); //Debug.WriteLine("All Downloaded"); foreach (DownloadFileInfo file in this.allFileList) { string tempUrlPath = CommonUnitity.GetFolderUrl(file); string oldPath = string.Empty; string newPath = string.Empty; try { if (!string.IsNullOrEmpty(tempUrlPath)) { oldPath = Path.Combine(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1), file.FileName); newPath = Path.Combine(CommonUnitity.SystemBinUrl + ConstFile.TEMPFOLDERNAME + tempUrlPath, file.FileName); } else { oldPath = Path.Combine(CommonUnitity.SystemBinUrl, file.FileName); newPath = Path.Combine(CommonUnitity.SystemBinUrl + ConstFile.TEMPFOLDERNAME, file.FileName); } //just deal with the problem which the files EndsWith xml can not download System.IO.FileInfo f = new FileInfo(newPath); if (!file.Size.ToString().Equals(f.Length.ToString()) && !file.FileName.ToString().EndsWith(".xml")) { ShowErrorAndRestartApplication(); } //Added for dealing with the config file download errors string newfilepath = string.Empty; if (newPath.Substring(newPath.LastIndexOf(".") + 1).Equals(ConstFile.CONFIGFILEKEY)) { if (System.IO.File.Exists(newPath)) { if (newPath.EndsWith("_")) { newfilepath = newPath; newPath = newPath.Substring(0, newPath.Length - 1); oldPath = oldPath.Substring(0, oldPath.Length - 1); } File.Move(newfilepath, newPath); } } //End added if (File.Exists(oldPath)) { MoveFolderToOld(oldPath, newPath); } else { //Edit for config_ file if (!string.IsNullOrEmpty(tempUrlPath)) { if (!Directory.Exists(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1))) { Directory.CreateDirectory(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1)); MoveFolderToOld(oldPath, newPath); } else { MoveFolderToOld(oldPath, newPath); } } else { MoveFolderToOld(oldPath, newPath); } } } catch (Exception exp) { //log the error message,you can use the application's log code } } //After dealed with all files, clear the data this.allFileList.Clear(); if (this.downloadFileList.Count == 0) Exit(true); else Exit(false); evtDownload.Set(); } //To delete or move to old files void MoveFolderToOld(string oldPath, string newPath) { if (File.Exists(oldPath + ".old")) File.Delete(oldPath + ".old"); if (File.Exists(oldPath)) File.Move(oldPath, oldPath + ".old"); File.Move(newPath, oldPath); //File.Delete(oldPath + ".old"); } delegate void ShowCurrentDownloadFileNameCallBack(string name); private void ShowCurrentDownloadFileName(string name) { if (this.labelCurrentItem.InvokeRequired) { ShowCurrentDownloadFileNameCallBack cb = new ShowCurrentDownloadFileNameCallBack(ShowCurrentDownloadFileName); this.Invoke(cb, new object[] { name }); } else { this.labelCurrentItem.Text = name; } } delegate void SetProcessBarCallBack(int current, int total); private void SetProcessBar(int current, int total) { if (this.progressBarCurrent.InvokeRequired) { SetProcessBarCallBack cb = new SetProcessBarCallBack(SetProcessBar); this.Invoke(cb, new object[] { current, total }); } else { this.progressBarCurrent.Value = current; this.progressBarTotal.Value = total; } } delegate void ExitCallBack(bool success); private void Exit(bool success) { if (this.InvokeRequired) { ExitCallBack cb = new ExitCallBack(Exit); this.Invoke(cb, new object[] { success }); } else { this.isFinished = success; this.DialogResult = success ? DialogResult.OK : DialogResult.Cancel; this.Close(); } } private void OnCancel(object sender, EventArgs e) { //bCancel = true; //evtDownload.Set(); //evtPerDonwload.Set(); ShowErrorAndRestartApplication(); } private void DealWithDownloadErrors() { try { //Test Network is OK or not. Config config = Config.LoadConfig(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstFile.FILENAME)); WebClient client = new WebClient(); client.DownloadString(config.ServerUrl); } catch (Exception) { //log the error message,you can use the application's log code ShowErrorAndRestartApplication(); } } private void ShowErrorAndRestartApplication() { MessageBox.Show(ConstFile.NOTNETWORK,ConstFile.MESSAGETITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); CommonUnitity.RestartApplication(); } #endregion } }