using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Windows.Forms; namespace ButcherFactory.AutoUpdate { public partial class Form1 : Form { const string serUri = "http://172.28.1.194:7799/AutoUpdate/ClientVersion.xml"; const string PuKey = "c756e02cedb42a33f78091a466411bde8447d854"; private bool isFinished = false; private List downloadFileList = null; private ManualResetEvent evtDownload = null; private ManualResetEvent evtPerDonwload = null; private WebClient clientDownload = null; ClientVersion old; bool error = false; public Form1(string[] args) { InitializeComponent(); if (args == null || args.Length == 0 || args[0] != PuKey) error = true; this.Load += Form1_Load; } void Form1_Load(object sender, EventArgs e) { if (error) Application.Exit(); var versionFile = "ClientVersion.xml"; old = new ClientVersion(); if (File.Exists(versionFile)) old = XmlUtil.DeserializeFromFile(); if (string.IsNullOrEmpty(old.ServerUrl)) old.ServerUrl = serUri; clientDownload = new WebClient(); var version = XmlUtil.XmlDeserializeObject(clientDownload.DownloadString(old.ServerUrl)); old.ServerUrl = version.ServerUrl; old.Version = version.Version; downloadFileList = version.UpdateFiles; evtDownload = new ManualResetEvent(true); evtDownload.Reset(); Thread t = new Thread(new ThreadStart(ProcDownload)); t.Name = "download"; t.Start(); } long total = 0; long nDownloadedTotal = 0; string startFile = "ButcherFactory.Login.exe"; string oldFolder; private void ProcDownload() { evtPerDonwload = new ManualResetEvent(false); foreach (var file in this.downloadFileList) { total += file.Size; } oldFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "old"); if (!Directory.Exists(oldFolder)) Directory.CreateDirectory(oldFolder); while (!evtDownload.WaitOne(0, false)) { if (this.downloadFileList.Count == 0) break; var file = this.downloadFileList[0]; if (file.NeedRestart) startFile = file.FileName; this.ShowCurrentDownloadFileName(file.FileName); //下载 clientDownload = new WebClient(); clientDownload.DownloadProgressChanged += new DownloadProgressChangedEventHandler(OnDownloadProgressChanged); clientDownload.DownloadFileCompleted += new AsyncCompletedEventHandler(OnDownloadFileCompleted); evtPerDonwload.Reset(); clientDownload.DownloadFileAsync(new Uri(file.Url), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, file.FileName + ".tmp"), file); //等待下载完成 evtPerDonwload.WaitOne(); clientDownload.Dispose(); clientDownload = null; //移除已下载的文件 this.downloadFileList.Remove(file); } if (this.downloadFileList.Count == 0) { Exit(true); evtDownload.Set(); XmlUtil.SerializerObjToFile(old); Process.Start(Path.Combine(Application.StartupPath, startFile)); Application.Exit(); } else Exit(false); evtDownload.Set(); } void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { var file = e.UserState as UpdateFile; nDownloadedTotal += file.Size; this.SetProcessBar(0, (int)(nDownloadedTotal * 100 / total)); //备份文件 string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, file.FileName); var oldFile = Path.Combine(oldFolder, file.FileName); if (File.Exists(filePath)) { if (File.Exists(oldFile)) File.Delete(oldFile); File.Move(filePath, oldFile); } File.Move(filePath + ".tmp", filePath); //继续下载其它文件 evtPerDonwload.Set(); } void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { this.SetProcessBar(e.ProgressPercentage, (int)((nDownloadedTotal + e.BytesReceived) * 100 / total)); } 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(); } } } }