4.1 准备一个XML配置文件
名称为AutoUpdater.xml,作用是作为一个升级用的模板,显示需要升级的信息。
Xml代码 收藏代码
<?xml version="1.0"?>
<AutoUpdater>
<URLAddres URL="http://www.dahuagong.com/update"/>
<UpdateInfo>
<UpdateTime Date = "2005-02-02"/>
<Version Num = "1.0.0.1"/>
</UpdateInfo>
<UpdateFileList>
<UpdateFile FileName = "aa.txt"/>
<UpdateFile FileName = "VB40.rar"/>
<UpdateFile FileName = "VB4-1.CAB"/>
</UpdateFileList>
<RestartApp>
<ReStart Allow = "Yes"/>
<AppName Name = "Tims.exe"/>
</RestartApp>
</AutoUpdater>
从以上XML文档中可以得知升级文档所在服务器端的地址、升级文档的更新日期、需要升级的文件列表,其中共有三个文件需升级:aa.txt、VB40.rar、VB4-1.CAB。以及是否允许重新启动应用程序和重新启动的应用程序名。
从以上XML文档中可以得知升级文档所在服务器端的地址、升级文档的更新日期、需要升级的文件列表,其中共有三个文件需升级:aa.txt、VB40.rar、VB4-1.CAB。以及是否允许重新启动应用程序和重新启动的应用程序名。
4.2 获取客户端应用程序及服务器端升级程序的最近一次更新日期
通过GetTheLastUpdateTime()函数来实现。
Java代码 收藏代码
private string GetTheLastUpdateTime(string Dir)
{
string LastUpdateTime = "";
string AutoUpdaterFileName = Dir + @"\AutoUpdater.xml";
if(!File.Exists(AutoUpdaterFileName))
return LastUpdateTime;
FileStream myFile = new FileStream(AutoUpdaterFileName,FileMode.Open);
XmlTextReader xml = new XmlTextReader(myFile);
while(xml.Read())
{
if(xml.Name == "UpdateTime")
{
LastUpdateTime = xml.GetAttribute("Date");
break;
}
}
xml.Close();
myFile.Close();
return LastUpdateTime;
}
通过XmlTextReader打开XML文档,读取更新时间从而获取Date对应的值,即服务器端升级文件的最近一次更新时间。
函数调用实现:
Java代码 收藏代码
string thePreUpdateDate = GetTheLastUpdateTime(Application.StartupPath);
Application.StartupPath指客户端应用程序所在的路径。
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
theFolder.FullName指在升级文档下载到客户机上的临时文件夹所在的路径。
4.3 比较日期
客户端应用程序最近一次更新日期与服务器端升级程序的最近一次更新日期进行比较。
Java代码 收藏代码
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
if(thePreUpdateDate != "")
{
if(Convert.ToDateTime(thePreUpdateDate)>=Convert.ToDateTime(theLastsUpdateDate))
{
MessageBox.Show("当前软件已经是最新的,无需更新!","系统提示",MessageBoxButtons.OK,MessageBoxIcon.@R_390_4045@ion);
this.Close();
}
}
this.labDownFile.Text = "下载更新文件";
this.labFileName.Refresh();
this.btnCancel.Enabled = true;
this.progressBar.Position = 0;
this.progressBarTotal.Position = 0;
this.progressBarTotal.Refresh();
this.progressBar.Refresh();
ArrayList List = GetDownFileList(GetTheUpdateURL(),theFolder.FullName);
string[] urls = new string[List.Count];
List.copyTo(urls,0);
将客户端升级的应用程序的日期与服务器端下载的应用程序日期进行比较,如果前者大于后者,则不更新;如果前者小于后者,则通过动态数组获取下载文件的列表,开始下载文件。
通过BatchDownload()函数来实现。升级程序检测旧的主程序是否活动,若活动则关闭旧的主程序;删除旧的主程序,拷贝临时文件夹中的文件到相应的位置;检查主程序的状态,若状态为活动的,则启动新的主程序。
Java代码 收藏代码
private void BatchDownload(object data)
{
this.Invoke(this.activeStateChanger,new object[]{true,false});
try
{
DownloadInstructions instructions = (DownloadInstructions) data;
using(BatchDownloader bDL = new BatchDownloader())
{
bDL.CurrentProgressChanged +=
new DownloadProgressHandler(this.SingleProgressChanged);
bDL.StateChanged +=
new DownloadProgressHandler(this.StateChanged);
bDL.FileChanged +=
new DownloadProgressHandler(bDL_FileChanged);
bDL.TotalProgressChanged +=
new DownloadProgressHandler(bDL_TotalProgressChanged);
bDL.Download(instructions.URLs,instructions.Destination,(ManualResetEvent) this.cancelEvent);
}
}
catch(Exception ex)
{
ShowErrorMessage(ex);
}
this.Invoke(this.activeStateChanger,new object[]{false,false});
this.labFileName.Text = "";
if(this._Update)
{
this.labDownFile.Text = "正在关闭程序....";
System.Diagnostics.Process[] proc=
System.Diagnostics.Process.GetProcessesByName("Tims");
foreach(System.Diagnostics.Process pro in proc)
{
pro.Kill();
}
DirectoryInfo theFolder=new DirectoryInfo(Path.GetTempPath()+"JurassicUpdate");
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)); } } //启动安装程序 this.labDownFile.Text = "正在启动程序...."; System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "Tims.exe"); this.Close(); } } 这段程序是实现在线升级的关键代码,步骤有点复杂:首先用Invoke方法同步调用状态改变进程,然后调用动态链接库中批量下载 (BatchDownloader.cs)类启动批量下载,接着判断原有的主应用程序有没有关闭,如果没关闭,则用Process.Kill()来关闭主 程序。接下来,判断临时文件夹下(即下载升级程序所在的目录)是否存在与应用程序所在目录下的文件同名的文件,如果存在同名文件,则删除应用程序目录下的 文件,然后将临时文件夹的文件移到应用程序所在的目录下。最后重新启动主应用程序。这样更新就完成了。
【转自】http://chanshui.iteye.com/blog/729320