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;
}
}
}