您的位置:首页 > 编程语言 > C#

在WinForm中使用Web Services 来实现 软件 自动升级( Auto Update ) (C#) skyover [原作]

2004-06-24 10:22 1271 查看


Click Here
  首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类我的文档
最新文章发表文章
专栏管理使用说明
 RSS 订阅 
<
4000
/tr>
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    
积极原创作者 
wildhorseli (1)
eorr (2)
zf0579 (6)
cuizm (2)
baikeley1974 (3)
andiyang (1)
guojiafuzhuxi (1)
Kamus (8)
JavaD (2)
jimzj (9)
CSDN - 文档中心 - .NET 阅读:469   评论: 0    参与评论
标题  在WinForm中使用Web Services 来实现 软件 自动升级( Auto Update ) (C#)     skyover [原作]
关键字  WinForm,Web Services,Update
出处 
winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了这一缺陷,有较好的参考价值。
一、升级的好处。
       长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序的可维护性差,布置困难,升级不方便,维护成本高就是一个相当重要的因素,也是那些B/S的支持者们将Client/Server结构打入地狱的一个重要原因。
       现在好了,我们就在最新的基于Microsoft 的 WinForm上用WebServices来实现软件的自动升级功能。
二、升级的技术原理。
        升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级。当然也有人用其它属性比较的,例如:文件大小。:) 或者更新日期。
        而实现的方法呢?在VB时代,我使用的是XmlHTTP+INet控件。用XmlHTTP获取信息,用INET传输升级文件,而用一个简单的BAT文件来实现升级。
Public Sub CheckUpdate() On Error Resume Next Dim b As Boolean Dim XmlHttp As Object Set XmlHttp = CreateObject("Microsoft.XMLHttp") XmlHttp.Open "GET", "Http://mu.5inet.net/MuAdmin/update.xml", False XmlHttp.Send Dim vs As String vs = XmlHttp.responseText If Err.Number > 0 Then Exit Sub End If Dim Xml As Object Set Xml = CreateObject("Microsoft.XmlDom") Xml.LoadXml vs Dim Version As String Dim downAddr As String Dim FSize As Long Dim fInfo As String Version = Xml.DocumentElement.ChildNodes(0).Text downAddr = Xml.DocumentElement.ChildNodes(1).Text FSize = CLng(Xml.DocumentElement.ChildNodes(2).Text) fInfo = Xml.DocumentElement.ChildNodes(3).Text Set Xml = Nothing Set XmlHttp = Nothing Dim Major As Long Dim Minor As Long Dim Revision As Long Dim C() As String C = Split(Version, ".") Major = CLng(C(0)) Minor = CLng(C(1)) Revision = CLng(C(2)) If Major > App.Major Then b = True ElseIf Minor > App.Minor Then b = True ElseIf Revision > App.Revision Then b = True Else b = False End If If (b) Then Dim result As VbMsgBoxResult result = MsgBox("发现程序新版本。当前版本为:" & App.Major & "." & App.Minor & "." & App.Revision & ",目前最新版本为:" & Version & ",是否进行更新?", vbQuestion Or vbYesNo, "自动更新") If result = vbYes Then Dim frm As New Update frm.DownloadAddress = downAddr frm.size = FSize frm.InfoPage = fInfo frm.Version = Version frm.Show vbModal End If End If End Sub

      而BAT文件有个特性,是可以删除自己本身。下面是BAT文件的内容.
@echo off echo echo echo 欢迎使用无垠奇迹管理器升级向导。 echo 本次升级版本为:1.1.0。 echo 请按任意键开始升级无垠奇迹管理器... echo echo pause del SQLSrvBrowser.Exe ren ~update.tmp SQLSrvBrowser.Exe echo 升级成功,按任意键重新启动应用程序。 pause start http://mu.5inet.net/ start SQLSrvBrowser.Exe del update.bat

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

        实现原理:在WebServices中实现一个GetVer的WebMethod方法,其作用是获取当前的最新版本。
   然后将现在版本与最新版本比较,如果有新版本,则进行升级。
  步骤:
    1、准备一个XML文件 (Update.xml)。
<?xml version="1.0" encoding="utf-8" ?>
<product>
 <version>1.0.1818.42821</version>
 <description>修正一些Bug</description>
 <filelist count="4" sourcepath="./update/">
  <item name="City.xml" size="">
   <value />
  </item>
  <item name="CustomerApplication.exe" size="">
   <value />
  </item>
  <item name="Interop.SHDocVw.dll" size="">
   <value />
  </item>
  <item name="Citys.xml" size="">
   <value />
  </item>
 </filelist>
</product>
作用是作为一个升级用的模板。
    2、WebServices的GetVer方法。
[WebMethod(Description="取得更新版本")] public string GetVer() { XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("update.xml")); XmlElement root = doc.DocumentElement; return root.SelectSingleNode("version").InnerText; }

     3、WebServices的GetUpdateData方法。
[WebMethod(Description="在线更新软件")] [SoapHeader("sHeader")] public System.Xml.XmlDocument GetUpdateData() { //验证用户是否登陆  if(sHeader==null) return null; if(!DataProvider.GetInstance.CheckLogin(sHeader.Username,sHeader.Password)) return null; //取得更新的xml模板内容  XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("update.xml")); XmlElement root = doc.DocumentElement; //看看有几个文件需要更新  XmlNode updateNode = root.SelectSingleNode("filelist"); string path = updateNode.Attributes["sourcepath"].Value; int count = int.Parse(updateNode.Attributes["count"].Value); //将xml中的value用实际内容替换  for(int i=0;i<count;i++) { XmlNode itemNode = updateNode.ChildNodes[i]; string fileName = path + itemNode.Attributes["name"].Value; FileStream fs = File.OpenRead(Server.MapPath(fileName)); itemNode.Attributes["size"].Value = fs.Length.ToString(); BinaryReader br = new BinaryReader(fs); //这里是文件的实际内容,使用了Base64String编码  itemNode.SelectSingleNode("value").InnerText = Convert.ToBase64String(br.ReadBytes((int)fs.Length),0,(int)fs.Length); br.Close(); fs.Close(); } return doc; }
    4、在客户端进行的工作。
      首先引用此WebServices,例如命名为:WebSvs,
     string nVer = Start.GetService.GetVer(); 
     if(Application.ProductVersion.CompareTo(nVer)<=0)
      update(); 在本代码中 Start.GetService是WebSvs的一个Static 实例。首先检查版本,将结果与当前版本进行比较,
如果为新版本则执行UpDate方法。

void update() { this.statusBarPanel1.Text = "正在下载..."; System.Xml.XmlDocument doc = ((System.Xml.XmlDocument)Start.GetService.GetUpdateData()); doc.Save(Application.StartupPath + @"/update.xml"); System.Diagnostics.Process.Start(Application.StartupPath + @"/update.exe"); Close(); Application.Exit(); }
这里为了简单起见,没有使用异步方法,当然使用异步方法能更好的提高客户体验,这个需要读者们自己去添加。
:) update的作用是将升级的XML文件下载下来,保存为执行文件目录下的一个Update.xml文件。任务完成,
退出程序,等待Update.Exe 来进行升级。
 
    5、Update.Exe 的内容。
 
private void Form1_Load(object sender, System.EventArgs e) { System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses(); foreach(System.Diagnostics.Process p in ps) { //MessageBox.Show(p.ProcessName);  if(p.ProcessName.ToLower()=="customerapplication") { p.Kill(); break; } } XmlDocument doc = new XmlDocument(); doc.Load(Application.StartupPath + @"/update.xml"); XmlElement root = doc.DocumentElement; XmlNode updateNode = root.SelectSingleNode("filelist"); string path = updateNode.Attributes["sourcepath"].Value; int count = int.Parse(updateNode.Attributes["count"].Value); for(int i=0;i<count;i++) { XmlNode itemNode = updateNode.ChildNodes[i]; string fileName = itemNode.Attributes["name"].Value; FileInfo fi = new FileInfo(fileName); fi.Delete(); //File.Delete(Application.StartupPath + @"/" + fileName);  this.label1.Text = "正在更新: " + fileName + " (" + itemNode.Attributes["size"].Value + ") ..."; FileStream fs = File.Open(fileName,FileMode.Create,FileAccess.Write); fs.Write(System.Convert.FromBase64String(itemNode.SelectSingleNode("value").InnerText),0,int.Parse(itemNode.Attributes["size"].Value)); fs.Close(); } label1.Text = "更新完成"; File.Delete(Application.StartupPath + @"/update.xml"); label1.Text = "正在重新启动应用程序..."; System.Diagnostics.Process.Start("CustomerApplication.exe"); Close(); Application.Exit(); }
 
这个代码也很容易懂,首先就是找到主进程,如果没有关闭,则用Process.Kill()来关闭主程序。然后则用一个
XmlDocument来Load程序生成的update.xml文件。用xml文件里指定的路径和文件名来生成指定的文件,在这之
前先前已经存在的文件删除。更新完毕后,则重新启动主应用程序。这样更新就完成了。
四、总结:
  从这个实例看来,WebService的工作是很简单的,也是很容易实现的。好好的使用WebService能够为我们
的程序带来很多新的,强的功能。总而言之,.Net是易用的,强大的语言。如果大家对本代码有任何意见,欢迎
光临《开发者》论坛: http://forums.coder.cn/ ,希望和大家共同探讨。
此文亦发表在本人Blog上:http://blogs.coder.cn/skyover/archive/2004/06/07/485.aspx
对该文的评论
[align=right]【评论】 【关闭】 [/align]
网站简介 - 广告服务 - 网站地图 - 帮助信息 - 联系方式 - English
北京百联美达美数码科技有限公司 版权所有 京ICP证020026号
Copyright ? CSDN.NET, Inc. All Rights Reserved
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐