在WinForm中使用WebServices来实现软件自动升级(AutoUpdate)(C#)

winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了这一缺陷,有较好的参考价值。

一、升级的好处。
       长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序的可维护性差,布置困难,升级不方便,维护成本高就是一个相当重要的因素,也是那些B/S的支持者们将Client/Server结构打入地狱的一个重要原因。

       现在好了,我们就在最新的基于Microsoft 的 WinForm上用WebServices来实现软件的自动升级功能。

二、升级的技术原理。
        升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级。当然也有人用其它属性比较的,例如:文件大小。:) 或者更新日期。

三、在.Net的实现。
        在.Net时代,我们就有了更多的选择,可以使用WebRequest,也可以使用WebServices。在这里我们将用WebServices来实现软件的自动升级。

        实现原理:在WebServices中实现一个GetVer的WebMethod方法,其作用是获取当前的最新版本。
   然后将现在版本与最新版本比较,如果有新版本,则进行升级。

  步骤:
    1、准备一个XML文件 (Update.xml)。

 

 1  <? xml version="1.0" encoding="utf-8"  ?> 
 2  < product >
 3
    < version > 1.0.1818.42821 </ version >
 4
    < description > 修正一些Bug </ description >
 5
    < filelist  count ="4"  sourcepath ="./update/" >
 6
     < item  name ="City.xml"  size ="" >
 7
      < value  />
 8
     </ item >
 9
     < item  name ="CustomerApplication.exe"  size ="" >
10
      < value  />
11
     </ item >
12
     < item  name ="Interop.SHDocVw.dll"  size ="" >
13
      < value  />
14
     </ item >
15
     < item  name ="Citys.xml"  size ="" >
16
      < value  />
17
     </ item >
18
    </ filelist >
19
  </ product >

 

作用是作为一个升级用的模板。
    2、WebServices的GetVer方法。

1  [WebMethod(Description = " 取得更新版本")]
2           public  string GetVer()
3          {
4              XmlDocument doc  =  new XmlDocument();
5              doc.Load(Server.MapPath( " update.xml"));
6              XmlElement root = doc.DocumentElement;
7               return  root.SelectSingleNode( " version").InnerText;
8          }


3、WebServices的GetUpdateData方法。

 1  [WebMethod(Description = " 在线更新软件")]
 2          [SoapHeader( " sHeader")]
 3          public System.Xml.XmlDocument GetUpdateData()
 4          {
 5               //验证用户是否登陆
 6
               if (sHeader ==null)
 7                   return  null;
 8               if (!DataProvider.GetInstance.CheckLogin(sHeader.Username,sHeader.Password))
 9                   return  null;
10               //取得更新的xml模板内容
11
              XmlDocument doc  =  new XmlDocument();
12              doc.Load(Server.MapPath( " update.xml"));
13              XmlElement root = doc.DocumentElement;
14               //看看有几个文件需要更新
15
              XmlNode updateNode  =  root.SelectSingleNode( " filelist"); 
16               string  path  =  updateNode.Attributes[ " sourcepath"].Value;
17               int  count  =   int .Parse(updateNode.Attributes[ " count"].Value);
18               //将xml中的value用实际内容替换
19
               for ( int  i = 0 ;i < count;i++)
20              {
21                  XmlNode itemNode = updateNode.ChildNodes[i];
22                   string  fileName  =  path  +  itemNode.Attributes[ " name"].Value;
23                  FileStream fs = File.OpenRead(Server.MapPath(fileName));
24                  itemNode.Attributes[ " size " ].Value = fs.Length.ToString();
25                  BinaryReader br  =  new BinaryReader(fs);
26                   //这里是文件的实际内容,使用了Base64String编码
27
                  itemNode.SelectSingleNode( " value " ).InnerText  =  Convert.ToBase64String(br.ReadBytes(( int )fs.Length), 0 ,(int)fs.Length);
28                  br.Close();
29                  fs.Close();
30              }
31              return doc;
32          }

4、在客户端进行的工作。
      首先引用此WebServices,例如命名为:WebSvs,

1  string  nVer = Start.GetService.GetVer(); 
2        if (Application.ProductVersion.CompareTo(nVer) <=0)
3        update();

在本代码中 Start.GetService是WebSvs的一个Static 实例。首先检查版本,将结果与当前版本进行比较,
如果为新版本则执行UpDate方法。

1  void update()
2          {
3               this .statusBarPanel1.Text  =   " 正在下载...";
4              System.Xml.XmlDocument doc = ((System.Xml.XmlDocument)Start.GetService.GetUpdateData());
5              doc.Save(Application.StartupPath  +   @" \update.xml");
6              System.Diagnostics.Process.Start(Application.StartupPath  +   @" \update.exe");
7              Close();
8              Application.Exit();
9          }

这里为了简单起见,没有使用异步方法,当然使用异步方法能更好的提高客户体验,这个需要读者们自己去添加。
:) update的作用是将升级的XML文件下载下来,保存为执行文件目录下的一个Update.xml文件。任务完成,
退出程序,等待Update.Exe 来进行升级。

5、Update.Exe 的内容。

 

 1  private   void  Form1_Load( object  sender, System.EventArgs e)
 2          {
 3              System.Diagnostics.Process[] ps  =  System.Diagnostics.Process.GetProcesses();
 4               foreach (System.Diagnostics.Process p  in  ps)
 5              {
 6                   // MessageBox.Show(p.ProcessName);
 7                   if (p.ProcessName.ToLower() == " customerapplication " )
 8                  {
 9                      p.Kill();
10                       break ;
11                  }
12              }
13              XmlDocument doc  =   new  XmlDocument();
14              doc.Load(Application.StartupPath  +   @" \update.xml " );
15              XmlElement root  =  doc.DocumentElement;
16              XmlNode updateNode  =  root.SelectSingleNode( " filelist " );
17               string  path  =  updateNode.Attributes[ " sourcepath " ].Value;
18               int  count  =   int .Parse(updateNode.Attributes[ " count " ].Value);
19               for ( int  i = 0 ;i < count;i ++ )
20              {
21                  XmlNode itemNode  =  updateNode.ChildNodes[i];
22                   string  fileName  =  itemNode.Attributes[ " name " ].Value;
23                  FileInfo fi  =   new  FileInfo(fileName);
24                  fi.Delete();
25                   // File.Delete(Application.StartupPath + @"\" + fileName);
26                   this .label1.Text  =   " 正在更新:  "   +  fileName  +   "  ( "   +  itemNode.Attributes[ " size " ].Value  +   " ) ... " ;
27                  FileStream fs  =  File.Open(fileName,FileMode.Create,FileAccess.Write);
28                  fs.Write(System.Convert.FromBase64String(itemNode.SelectSingleNode( " value " ).InnerText), 0 , int .Parse(itemNode.Attributes[ " size " ].Value));
29                  fs.Close();
30              }
31              label1.Text  =   " 更新完成 " ;
32              File.Delete(Application.StartupPath  +   @" \update.xml " );
33              label1.Text  =   " 正在重新启动应用程序... " ;
34              System.Diagnostics.Process.Start( " CustomerApplication.exe " );
35              Close();
36              Application.Exit();
37          }

 

这个代码也很容易懂,首先就是找到主进程,如果没有关闭,则用Process.Kill()来关闭主程序。然后则用一个
XmlDocument来Load程序生成的update.xml文件。用xml文件里指定的路径和文件名来生成指定的文件,在这之
前先前已经存在的文件删除。更新完毕后,则重新启动主应用程序。这样更新就完成了。


 

你可能感兴趣的:(WebServices)