可复用的自动升级系统C#实现(二)

        上一篇文章解决了实现可复用的自动升级系统的思路,这篇文章将给出UpdateActionSystem.exe的参考实现及相关的牵涉主程序的代码。

UpdateActionSystem.exe的主窗体UpdatingForm的主要成员如下:

  private UpdateConfigParser updateParser = null ;//用于解析版本配置文件UpdateConfig.xml
  private DealSoftwareVersion dealVersion = null ;//用于访问数据库的SoftwareVersion表
  private string curApppath = null ; //当前路径

//构造函数中初始化各成员

#region ctor
  public UpdatingForm()
  {   
   InitializeComponent(); 
 
   this.curApppath = System.IO.Directory.GetParent(Application.ExecutablePath).ToString();  
   this.progressControl2.SetIDealEvent(this) ;

   this.updateParser = new UpdateConfigParser(this.curApppath + "//UpdateConfig.xml") ;
   string connStr = ...... ;

   this.dealVersion = new DealSoftwareVersion(connStr) ;
  }
  #endregion

//下载新版本文件的线程:

#region DownloadThread
  private void DownloadThread()
  {
   int succeedCount = 0 ;
   int failCount = 0 ;

   
   SoftwareVersion[] versions = null ;

   try
   {    
    versions = (SoftwareVersion[])this.dealVersion.GetObjects("") ;
    if((versions == null) || (versions.Length == 0))
    {
     MessageBox.Show("没有任何文件需要升级!") ;
     this.Close() ;
    }
   }
   catch
   {
    MessageBox.Show("无法与数据库服务器建立连接,可能是服务器已关闭!升级失败!") ;
    this.Close() ;
   }

   for(int i=0 ;i<versions.Length ;i++)
   {
    if((versions[i].SoftwareType != this.updateParser.SoftwareType) && (versions[i].SoftwareType != this.updateParser.CommonSoftwareTypeName))
    {
     continue ;
    }

    string softName = versions[i].SoftwareName ;
    decimal newVer  = versions[i].Version ;
    string url      = versions[i].URL ;
    string filePath = this.curApppath + "//" + softName ;

    bool isExit = this.updateParser.IsSoftwareExit(softName) ;
    if(isExit)
    {
     decimal oldVer = this.updateParser.GetSoftwareVersion(softName) ;

     if(oldVer < newVer) //覆盖旧文件
     {
      this.SetTitle(softName ,true) ;
      bool succeed = this.DownLoadOneFile(url ,filePath ,this.progressControl2) ;
      if(succeed)
      {
       this.updateParser.SetNewVersion(softName ,newVer) ;
       ++ succeedCount ;
       this.DisplayMsg(string.Format("成功升级{0}文件!" ,softName)) ;
      }
      else
      {
       ++ failCount ;
       this.DisplayMsg(string.Format("升级{0}文件失败!" ,softName)) ;
      }
     }
    }
    else //下载新文件
    {
     this.SetTitle(softName ,false) ;
     this.updateParser.AddNewSoftware(softName ,newVer) ;
     bool succeed = this.DownLoadOneFile(url ,filePath ,this.progressControl2) ;
      
     if(succeed)
     {
      ++ succeedCount ;
      this.DisplayMsg(string.Format("成功下载{0}文件!" ,softName)) ;
     }
     else
     {
      ++ failCount ;
      this.updateParser.SetNewVersion(softName ,0) ;
      this.DisplayMsg(string.Format("下载{0}文件失败!" ,softName)) ;
     }
    }    
   }
   
   string msg = null ;
   if(succeedCount+failCount == 0)
   {
    msg = "没有任何文件需要更新!" ;
   }
   else if((succeedCount > 0) && (failCount == 0))
   {
    msg = string.Format("成功更新{0}个文件!",succeedCount) ;
   }
   else
   {
    msg = string.Format("总共需要更新{0}个文件,成功更新{1}个文件!有{2}个文件更新失败!" , succeedCount+failCount ,succeedCount ,failCount) ;
   }

   MessageBox.Show(msg) ;

   this.Close() ;
  }  
  #endregion

//下载某个文件的方法

#region DownLoadOneFile
  private bool DownLoadOneFile(string url ,string filePath ,ProgressControl proControl)
  {
   FileStream fstream  = new FileStream(filePath ,FileMode.Create ,FileAccess.Write);
   WebRequest wRequest =  WebRequest.Create(url);

   try
   {    
    WebResponse wResponse = wRequest.GetResponse(); 
    int contentLength =(int)wResponse.ContentLength;    
            
    byte[] buffer = new byte[1024];
    int read_count = 0 ;
    int total_read_count = 0 ;
    bool complete = false;

    proControl.SetParas(0 ,contentLength ,buffer.Length) ;     
    
    while (!complete )
    {
     read_count = wResponse.GetResponseStream().Read(buffer,0,buffer.Length);
     
     if(read_count > 0)
     {      
      fstream.Write(buffer ,0 ,read_count) ;
      total_read_count += read_count ;
      if(total_read_count <= contentLength)
       proControl.step_forward() ;     
     } 
     else
     {
      complete = true ;
     }
    }
    
    fstream.Flush() ;
    return true ;
   }
   catch(Exception ee)
   {  
    ee = ee ;
    return false ;
   }
   finally
   {    
    fstream.Close() ;    
    wRequest = null;
   }

  }
  #endregion  

//在窗体加载时,启动下载线程

#region Form1_Load
  private void Form1_Load(object sender, System.EventArgs e)
  {
   System.Threading.Thread.Sleep(1000) ;
   ThreadDelegate thread = new ThreadDelegate(this.DownloadThread) ;
   thread.BeginInvoke(null ,false) ; //异步执行
  }
  #endregion

UpdateActionSystem.exe的主要实现代码就是这些,下面给出主应用程序中的相关代码:

在登录窗体的构造函数中:

   //检查自动更新
   bool needUpdate  = this.NeedToUpdate() ;  
   this.linkLabel_update.Visible = needUpdate ;
   this.button_logon.Enabled = (! needUpdate) ;

  //点击linkLabel_update将启动UpdateActionSystem.exe

private void linkLabel_update_LinkClicked(object sender, System.Windows.Forms.LinkLabel_updateClickedEventArgs e)
  {
   Process downprocess = new Process();
   string apppath = System.IO.Directory.GetParent(Application.ExecutablePath).ToString();
   downprocess.StartInfo.FileName = string.Format("{0}//{1}" , apppath ,UpdateActionSystem.exe) ;
   downprocess.Start();
   this.DialogResult = DialogResult.Cancel;
   return;  
  }

好了,主要的实现代码都给出来了。

 

2014.08.21 可复用的自动升级系统已经经过N次重构,重新命名为OAUS,并开放源码,请参见 http://blog.oraycn.com/OAUS.aspx

 

 

你可能感兴趣的:(String,C#,null,buffer,数据库服务器)