軟件自動在線升級的原理

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服務器

相關文章
相關標籤/搜索