软件自动在线升级的原理

4.1 准备一个XML配置文件

 名称为AutoUpdater.xml,作用是作为一个升级用的模板,显示需要升级的信息。 
Xml代码  收藏代码
<?xml version="1.0"?//xml版本号 
<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;   

    //打开xml文件 
    FileStream myFile = new FileStream(AutoUpdaterFileName,FileMode.Open);   
    //xml文件阅读器 
    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.Information);   
        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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇