主窗体:Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Net;
using System.Collections;
using System.Threading;
namespace Update
{
public partial class Form1 : Form
{
static public Form1 form; //
public Form1()
{
InitializeComponent();
LabNotice.Text = "";
labDownSize.Text = "";
btnCancel.Enabled = false;
form = this;
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//vs2005里面是禁止线程间的互相调用的,所以要手工设置
}
private void btnUpdate_Click(object sender, EventArgs e) //开始更新,创建更新进程,见Update.cs
{
btnUpdate.Enabled = false;
btnCancel.Enabled = true;
Update up = new Update();
Thread th = new Thread(up.BegUpdate);
th.Start();
}
}
}
实现更新的类:Update.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Net;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.ComponentModel;
namespace Update
{
class Update
{
private string URLAddress; //服务器地址
private string[] UpdateFiles; //更新文件的名字
private string[] LenUpdateFiles; //每个文件的大小
private bool BoolDownload = true; //是否有文件正在下载
private long AllSize = 0, DownSize = 0, PreSize = 0; //文件总大小,已经下了多少,完整的文件已经下了多少
private Form1 form = Form1.form; //为了方便控制主窗体
public void BegUpdate() //开始更新
{
URLAddress = ReadXml(Application.StartupPath + "\\update.xml", "URLAddres", "URL");
DownloadXml("update.xml"); //从服务器下载最新的xml
CompareVersion(); //比较自己程序和服务器上程序的版本号
}
private void PreDown() //下载前的准备
{
if (!Directory.Exists(Application.StartupPath + "\\temp"))
{
Directory.CreateDirectory(Application.StartupPath + "\\temp");
}
}
private void DownloadXml(string Name) //从服务器下载XML文件
{
if (File.Exists(Application.StartupPath + "\\temp\\" + Name))
File.Delete(Application.StartupPath + "\\temp\\" + Name);
WebRequest myre = null;
try
{
myre = WebRequest.Create(URLAddress + "\\" + Name);
myre.Method = "HEAD";
}
catch (WebException exp)
{
MessageBox.Show(exp.Message, "Error");
}
WebClient client = new WebClient();
Uri Url = new Uri(URLAddress + Name);
client.DownloadFile(Url, Application.StartupPath + "\\temp\\" + Name);
}
private string ReadXml(string Path, string NodeName, string Name) //读取XML
{
string XmlValue = "";
if (!File.Exists(Path))
return XmlValue;
//打开xml文件
FileStream myFile = new FileStream(Path, FileMode.Open);
//xml文件阅读器
XmlTextReader xml = new XmlTextReader(myFile);
while (xml.Read())
{
if (xml.Name == NodeName)
{
//获取升级文档的最后一次更新日期
XmlValue = xml.GetAttribute(Name);
break;
}
}
xml.Close();
myFile.Close();
return XmlValue;
}
private void CompareVersion() //比较版本号
{
//获得已下载文档的最近一次更新日期
string OldVersion = ReadXml(Application.StartupPath + "\\update.xml", "Version", "Num");
string NewVersion = ReadXml(Application.StartupPath + "\\temp\\update.xml", "Version", "Num");
//如果客户端将升级的应用程序的更新日期大于服务器端升级的应用程序的更新日期
if (string.Compare(OldVersion, NewVersion) >= 0)
{
MessageBox.Show("当前软件已经是最新的,无需更新!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(0);
}
form.LabNotice.Text = "下载更新文件";
form.LabNotice.Refresh();
form.btnCancel.Enabled = true;
//通过动态数组获取下载文件的列表
ArrayList List = GetDownFileList();
UpdateFiles = new string[List.Count];
List.CopyTo(UpdateFiles, 0);
GetAllSize();
BatchDownload();
}
private void GetAllSize() //获取所有更新文件的大小
{
ArrayList al = new ArrayList();
foreach (string UpdateFile in UpdateFiles)
{
WebRequest myre = WebRequest.Create(URLAddress + "\\" + UpdateFile);
WebResponse wr = myre.GetResponse();
al.Add(wr.ContentLength.ToString());
AllSize += wr.ContentLength;
}
LenUpdateFiles = new string[al.Count];
al.CopyTo(LenUpdateFiles, 0);
form.progressBarTotal.Maximum = (int)AllSize;
}
private ArrayList ReadXmlFile(string Path, string NodeName, string Name, ref int Count) //读取XML中要更新的所有文件名
{
ArrayList List = new ArrayList();
if (!File.Exists(Path))
return null;
//打开xml文件
FileStream myFile = new FileStream(Path, FileMode.Open);
//xml文件阅读器
XmlTextReader xml = new XmlTextReader(myFile);
while (xml.Read())
{
if (xml.Name == NodeName)
{
//获取升级文档的最后一次更新日期
List.Add(xml.GetAttribute(Name));
}
}
xml.Close();
myFile.Close();
return List;
}
private ArrayList GetDownFileList() //获取要更新的文件
{
int Count = 0;
ArrayList List = ReadXmlFile(Application.StartupPath + "\\update.xml", "UpdateFile", "FileName", ref Count);
return List;
}
private void Download(string Name, string size) //从服务器下载文件
{
if (File.Exists(Application.StartupPath + "\\temp\\" + Name))
File.Delete(Application.StartupPath + "\\temp\\" + Name);
WebRequest myre = null;
try
{
myre = WebRequest.Create(URLAddress + "\\" + Name);
myre.Method = "HEAD";
}
catch (WebException exp)
{
MessageBox.Show(exp.Message, "Error");
}
form.progressBar.Maximum = int.Parse(size);
WebClient MyWebClient = new WebClient();
Uri Url = new Uri(URLAddress + Name);
MyWebClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(MyWebClient_DownloadProgressChanged);
MyWebClient.DownloadFileCompleted += new AsyncCompletedEventHandler(MyWebClient_DownloadFileCompleted);
MyWebClient.DownloadFileAsync(Url, Application.StartupPath + "\\temp\\" + Name);
}
//当下载了数据时
private void MyWebClient_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
DownSize = (long)e.BytesReceived + PreSize;
form.labDownSize.Text = DownSize + " / " + AllSize;
try
{
form.progressBar.Value = (int)e.BytesReceived; //控制当前进度条
}
catch
{
form.progressBar.Value = form.progressBar.Maximum;
}
try
{
form.progressBarTotal.Value = (int)PreSize + (int)e.BytesReceived; //控制总共进度条
}
catch
{
form.progressBarTotal.Value = form.progressBarTotal.Maximum;
}
}
private void MyWebClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) //下载结束
{
BoolDownload = false;
}
private void BatchDownload() //开始更新下载
{
int Pos = 0;
foreach (string UpdateFile in UpdateFiles)
{
BoolDownload = true;
form.progressBar.Value = 0;
Download(UpdateFile, LenUpdateFiles[Pos]);
while (BoolDownload)
{
Thread.Sleep(1000);
}
PreSize += long.Parse(LenUpdateFiles[Pos]);
form.listFileName.Items.Add(UpdateFile + ":" + LenUpdateFiles[Pos]);
Pos++;
}
MessageBox.Show("更新完毕!");
form.LabNotice.Text = "正在关闭程序....";
System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("QQ");
//关闭原有应用程序的所有进程,用QQ程序做测试
foreach (System.Diagnostics.Process pro in proc)
{
pro.Kill();
}
DirectoryInfo theFolder = new DirectoryInfo(Application.StartupPath + "\\temp");
if (theFolder.Exists)
{
foreach (FileInfo theFile in theFolder.GetFiles())
{
//如果临时文件夹下存在与应用程序所在目录下的文件同名的文件,则删除应用程序目录下的文件
if (File.Exists(Application.StartupPath + "\\" + Path.GetFileName(theFile.FullName)))
File.Delete(Application.StartupPath + "\\" + Path.GetFileName(theFile.FullName));
//将临时文件夹的文件移到应用程序所在的目录下
File.Move(theFile.FullName, Application.StartupPath + "\\" + Path.GetFileName(theFile.FullName));
}
}
//启动安装程序,用QQ做测试
form.LabNotice.Text = "正在启动程序....";
System.Diagnostics.Process.Start(@"C:\Program Files\Tencent\QQ\QQ.exe");
Environment.Exit(0);
}
}
}