public UpdateManager() { //1.初始化对象属性 this.LastUpdateInfo = new UpdateInfo(); this.NowUpdateInfo = new UpdateInfo(); //2.给属性赋值 this.GetLastUpdateInfo(); this.GetNewUpdateInfo(); } //属性 public UpdateInfo LastUpdateInfo { get; set; } public UpdateInfo NowUpdateInfo { get; set; } //是否需要更新,根据时间 public bool IsUpdate { get { DateTime dt1 = Convert.ToDateTime(this.LastUpdateInfo.UpdateTime); DateTime dt2 = Convert.ToDateTime(this.NowUpdateInfo.UpdateTime); return dt2 > dt1; } } //存放更新文件的临时目录 public string TempFilePath { get { string newTempPath = Environment.GetEnvironmentVariable("Temp") +"\updatefiles"; if (!Directory.Exists(newTempPath)) Directory.CreateDirectory(newTempPath); return newTempPath; } } //从本地获取上次更新的信息,并封装到属性(对比作用) private void GetLastUpdateInfo() { FileStream myFiles = new FileStream("UpdateList.xml", FileMode.Open); XmlTextReader xmlReader = new XmlTextReader(myFiles); while (xmlReader.Read()) { switch (xmlReader.Name) { case "URLAddress": this.LastUpdateInfo.UpdateFileUrl = xmlReader.GetAttribute("URL"); break; case "Version": this.LastUpdateInfo.Version = xmlReader.GetAttribute("Num"); break; case "UpdateTime": this.LastUpdateInfo.UpdateTime =Convert.ToDateTime( xmlReader.GetAttribute("Date")); break; default: break; } xmlReader.Close(); myFiles.Close(); } } //从服务器下载最新的更新信息并封装到属性 private void GetNewUpdateInfo() { //下载最新的跟新目录到临时目录 string newXmlTempPath = TempFilePath + "\UpdateList.xml"; WebClient objClient = new WebClient(); objClient.DownloadFile( this.LastUpdateInfo.UpdateFileUrl + "\UpdateList.xml", newXmlTempPath); //封装更新的信息 FileStream myfile = new FileStream(newXmlTempPath,FileMode.Open); XmlTextReader xmlReader = new XmlTextReader(myfile); this.NowUpdateInfo.FileList = new List<string[]>();//集合对象,使用前必须初始化 while (xmlReader.Read()) { switch (xmlReader.Name) { case "Version": this.NowUpdateInfo.Version = xmlReader.GetAttribute("Num"); break; case "UpdateTime": this.NowUpdateInfo.UpdateTime =Convert.ToDateTime( xmlReader.GetAttribute("Date")); break; case "UpdateFile": string ver = xmlReader.GetAttribute("Ver"); string fileName = xmlReader.GetAttribute("FileName"); string contentLength = xmlReader.GetAttribute("ContentLength"); this.NowUpdateInfo.FileList.Add(new string[] { fileName, contentLength, ver, "0" }); break; default: break; } } xmlReader.Close(); myfile.Close(); } //显示用于显示更新的委托 public delegate void ShowUpdateProgress(int fileIndex,int finishedPercent); //定义委托对象,在更新窗体中会有具体方法与之关联 public ShowUpdateProgress ShowUpdateProgressDelegate; //根据更新文件列表下载更新文件,并同步显示下载的进度 public void DownLoadFiles() { List<string[]> fileList = this.NowUpdateInfo.FileList;//使用变量代替属性 for (int i = 0; i < fileList.Count; i++) { //1.连接远程服务器的指定文件,并准备读取 string fileName = fileList[i][0];//文件名 string fileUrl = this.LastUpdateInfo.UpdateFileUrl + fileName;//当前需要下载的url //抽象类不能直接new WebRequest objWebRequest = WebRequest.Create(fileUrl);//根据文件的url,连接服务器,创建请求对象 WebResponse objWebResponse = objWebRequest.GetResponse();//根据请求对象创建响应对象 Stream objStream = objWebResponse.GetResponseStream();//通过响应对象返回数据流对象 StreamReader objReader = new StreamReader(objStream);//用数据流对象作为参数创建流读取器对象 //2.在线读取已经连接的远程文件,基于委托反馈文件读取进度 long fileLength = objWebResponse.ContentLength;//通过响应对象获取接收的数据长度 byte[] bufferByte = new byte[fileLength];//根据当前文件的字节数创建字节数组 int allByte = bufferByte.Length;//得到总字节数 int startByte = 0;//表示第一个字节 while (fileLength > 0) { Application.DoEvents();//该语句表示允许在一个线程中同时处理其他的事件 int downLoadByte = objStream.Read(bufferByte, startByte, allByte);//开始读取字节流 if (downLoadByte == 0) break; startByte += downLoadByte;//累加下载的字节数 allByte -= downLoadByte;//未下载的字节数 //计算完成的百分比(整数) float part = (float)startByte / 1024; float total = (float)bufferByte.Length / 1024; int percent = Convert.ToInt32((part / total) * 100); //通过委托变量显示更新的百分比 ShowUpdateProgressDelegate(i,percent); } //3.保存读取完毕的文件 string newFileName = this.TempFilePath + "\" + fileName; FileStream fs = new FileStream(newFileName, FileMode.OpenOrCreate, FileAccess.Write); fs.Write(bufferByte, 0, bufferByte.Length); objStream.Close(); objReader.Close(); fs.Close(); } } //复制文件 public bool CopyFiles() { string[] files = Directory.GetFiles(TempFilePath);//获取文件数 foreach (string name in files) { string currentFile = name.Substring(name.LastIndexOf(@"") + 1); if (File.Exists(currentFile)) //文件在程序目录中存在,先删除 File.Delete(currentFile); File.Copy(name, currentFile); } return true; } }
xml配置:
<?xml version="1.0" encoding="UTF-8"?> -<AutoUpdater> <!--升级文件所在服务器端的网址--> <URLAddress URL="http://192.168.0.4/DownLoadFiles/"/> -<UpdateInfo> <!--升级文件的更新日期--> <UpdateTime Date="2017-01-22 12:00"/> <!--升级文件的版本号--> <Version Num="1.0.0.2"/> </UpdateInfo> -<UpdateFileList> <!--升级文件列表--> <UpdateFile ContentLength="21k" FileName="DAL.dll" Ver="1.0.0.2"/> <UpdateFile ContentLength="541k" FileName="StudentManager.exe" Ver="1.0.0.2"/> <UpdateFile ContentLength="6.77M" FileName="weixin.rar" Ver="1.0.0.2"/> </UpdateFileList> </AutoUpdater>
public class UpdateInfo { public string Version { get; set; } public DateTime UpdateTime { get; set; } public string UpdateFileUrl { get; set; } //跟新文件的信息列表(和listView的显示对应) public List<string[]> FileList { get; set; } }
public partial class Form1 : Form { private UpdateManager objUpdateManager = new UpdateManager(); public Form1() { InitializeComponent(); Init(); } private void Init() { this.btnFinshed.Visible = false; objUpdateManager.ShowUpdateProgressDelegate = this.ShowUpdateProgress; List<string[]> fileList = objUpdateManager.NowUpdateInfo.FileList; foreach (string[] item in fileList) { this.listView1.Items.Add(new ListViewItem(item)); } } //根据委托定义一个同步显示下载百分比的方法 private void ShowUpdateProgress(int fileIndex, int finishedPercent) { this.listView1.Items[fileIndex].SubItems[3].Text = finishedPercent + "%"; //进度条的显示 this.progressBar1.Maximum = 100; this.progressBar1.Value = finishedPercent; } private void btnNext_Click(object sender, EventArgs e) { this.btnNext.Visible = false; try { //开始下载文件,同时异步显示下载的百分比 this.objUpdateManager.DownLoadFiles(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btnFinshed_Click(object sender, EventArgs e) { try { if(objUpdateManager.CopyFiles()) //调用复制方法到程序根目录 { System.Diagnostics.Process.Start(""); //主程序的名称 //关闭升级程序 Application.ExitThread(); Application.Exit(); } } catch (Exception) { throw; } } }