C/S程序自动升级是一个很重要的功能,原理其实很简单,一般包含两个程序一个是主程序,也就是除了升级功能以外的程序,另一个就是升级程序,常见的360,金山安全卫士都是这样。

 主要包括以下几点:   1 比较版本  2下载文件  3更新文件 4启动主程序。但其中的需要注意的细节很多。

    一般服务端会有一个配置文件包含最新更新的文件信息的配置文件,当然这些更新信息也可以存到数据库,或者其他地方。客户端(也就是需要更新的那部分程序)也有一个配置文件包含客户端版本信息,这些信息可以存到专门的一个配置文件中,或者是config文件中,没有一定的规定,可以根据实际设计。

在客户端程序启动时,先启动更新程序通过比较本地版本和服务端最新的版本信息判断是否有新版本,如果有可以直接下载,下载完成替换成功后并更新客户端版本信息,启动主程序。

缺点:如果更新速度由于更新的文件很大或者网速很慢,用户不得不等待很长时间,直到下载完成或者下载失败。

优点:处理完成后,启动的直接就是更新后的程序。不会出现由于主程序在运行导致替换文件之类的错误。

另一种方法是, 在客户端段程序启动时,启动更新程序,但更新程序不做版本判断,到客户端更新目录下检查有没有下载的新版本,如果有就更新主程序并更新客户端版本信息,然后启动主程序,如果没有就直接启动主程序。由主程序判断是否有新版本,并在后台下载把文件放到客户端更新目录中,下载完成后,提示用户退出主程序,重新启动,在启动时由更新程序并更新客户端和客户端版本信息。

缺点:由于下载是在主程序的后台运行,可能会影响主程序的处理速度。

优点:避免了由于下载导致用户长时间的等待。

1 比较版本

比较依据:

可以通过文件的最后修改时间,或者使用文件版本作为比较依据,使用文件最后修改时间显然不是标准的做法,但也没有错误,但需要注意日期的格式一定要统一,避免日  期格式不一致导致错误。可以使用Fileinfo类获取最后修改时间,注意时间应该取服务器时间,编译程序集的机器时间应该相同,否则可能导致混乱。

FIleInfo类官网参考

使用文件版本作为标准,则每次修改时必须修改版本号,C#程序就是要修AssemblyInfo.cs文件中的内容了,多了一步,规范多了。Version类处理版本信息并比较。

 Assembly thisAssem = Assembly.GetExecutingAssembly();AssemblyName thisAssemName = thisAssem.GetName();Version ver = thisAssemName.Version;

Version类官网参考

当然也有其他的方式,例如MD5校验值比较,文件大小比较,之类的方法。不过个人认为文件大小缺陷很明显,新版本文件就一定比旧文件大吗?不一定吧。重构是可能变小的。

当然如果考虑客户端有不同的版本,都需要升级到最新的版本,显然不同的版本对应的升级文件不同,会更复杂,比较的信息也更多。

获取服务端版本信息:

如果服务端的版本信息存在数据库,直接读取数据库,就可以获取。如果存在配置文件,则可以通过webservice方法获取,或者请求一个网页 通过Response.Write();的方式获取信息,当然这两种方式都要建立虚拟目录或者网站。

2下载文件

存储位置:

如果新版本的文件存在数据库,就直接读取数据库,不过这种方式个人不建议使用,例如更新文件很大时性能不是很好。

存在固定虚拟目录的指定路径下,不失为一种好的方式,但客户端要下载,所以要注意一定要分配下载权限。

下载方式:

直接向通过虚拟路径发出请求,下载文件,由于虚拟路径有下载权限,如果更新需要判断是否有权限,例如要交费后才能下载则不好处理。

另一种方式是向一个网页发送请求,传递不同的查询字符串,网页 通过Response.BinaryWrite();的方式下载文件,则可以判断权限,当然麻烦一些是避免不了的。

下载文件代码

  Uri uri = new Uri(downFileUrl + localFileName);HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);request.Credentials = CredentialCache.DefaultCredentials;request.MaximumAutomaticRedirections = 4;localFileName = Path.GetFileName(localFileName);using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){Stream receiveStream = response.GetResponseStream();string newPath = Path.Combine(tempFold, localFileName);using (FileStream fs = new FileStream(newPath, FileMode.Create)){Byte[] buffer = new Byte[4096];int bytesRead = receiveStream.Read(buffer, 0, buffer.Length);while (bytesRead > 0){fs.Write(buffer, 0, bytesRead);bytesRead = receiveStream.Read(buffer, 0, buffer.Length);}}receiveStream.Close();}

3更新文件

更新类型:

直接替换的,例如修改了bug,直接替换的。

新增加的,例如新增加的功能做成了新的类库。

需要删除的,例如有些功能由于重构或者使用了了新方法不需要的。

需要执行的,例如写注册表,注册COM组件的。

每一种处理方式都不一样,需要根据类型分开处理

缺点:升级后,没办法取消升级,像windows的补丁程序可以安装,可以卸载的原理,目前还没有研究明白,希望知道的牛人指导。

当然也可以简单的先卸载,再安装,对于配置文件之类的信息特殊处理一下也可以。

当然如果考虑客户端有不同的版本,都需要升级到最新的版本,显然不同的版本对应的升级文件不同,会更复杂,但基本原理却不变。

4启动主程序

主程序路径的获取:

相对路径   主程序,更新程序,都使用相对路径,缺点是一旦相对路径确定后,后续的更新就不能更改这种目录关系。

注册表  路径都存入注册表,需要时通过注册表交互,主程序写注册表,更新程序读取注册表,缺点是读写注册表需要权限,写的路径也要固定,后续的更新不能改变写在注册表中的位置,也就是注册表路径。

运行程序代码

  private static void RunFile(string dir, string localFileName){string info = "运行程序" + localFileName;try{if (File.Exists(Path.Combine(dir, localFileName))){Process myProcess = new Process();ProcessStartInfo psi = new ProcessStartInfo();psi.FileName = localFileName;psi.WorkingDirectory = dir;psi.UseShellExecute = false;psi.RedirectStandardError = true;psi.CreateNoWindow = true;psi.RedirectStandardOutput = true;psi.WindowStyle = ProcessWindowStyle.Hidden;myProcess.StartInfo = psi;myProcess.Start();string error = myProcess.StandardError.ReadToEnd();string output = myProcess.StandardOutput.ReadToEnd();myProcess.WaitForExit();myProcess.Close();if (error != string.Empty){Log.Write("StandardError:" + error);}if (output != string.Empty){Log.Write("StandardOutput:" + output);}Log.LogProcessEnd(info);}}catch (Exception ex){Log.Write(info + "出错");Log.LogException(ex);throw ex;}}}

源代码下载

参考文章

参考文章2

参考文章3

作者:xuexiaodong2009 发表于2011-8-1 9:13:39 原文链接
阅读:5633 评论:37 查看评论

自动升级的原理及实现相关推荐

  1. 在WinForm中使用Web Services 来实现软件自动升级(转)

    一.升级的好处. 长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序的可维护性差,布置困难,升级不方便,维护 ...

  2. 强!chrome彻底关闭自动升级新方法实例演示,终于解决了chrome自动升级的烦恼

    我们做法是:清空Update文件夹,并设置权限,让chrome没有权限改这个文件夹. 原理:以往各种方法禁用chrome自动升级不成功,它有各种方法来升级谷歌,但一定是用update里的升级程序来升级 ...

  3. CAutoupdater通用 自动升级组件用户手册

    CAutoupdater通用 自动升级组件用户手册  CAutoupdater通用自动升级组件用户手册 1.CAutoupdater通用自动升级组件介绍 1.1.组件介绍 C/S构的特点是能充分发挥客 ...

  4. C# 实现在线软件自动升级自动下载更新文件

    1 前言 长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C /S结构的程序可维护性差,布置困难,升级不方便,维护成本高就 ...

  5. 在WinForm中使用Web Service来实现软件自动升级

    来源:互联网 winform程序相对web程序而言,功能更强大编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术 ...

  6. WPF开发一款软件自动升级组件

    前几天介绍了WPF进行自定义窗口的开发,关注的朋友还挺多,超出本人意料,呵呵,那么我就再接再励,在上篇的基础上,讲述一下软件自动升级组件的开发原理,大家时间宝贵,不想搞太长的篇幅,所以尽可能拣重要的说 ...

  7. SpringBoot自动配置Redis原理

    SpringBoot自动配置Redis原理 目录 SpringBoot自动配置Redis原理 一.SpringBoot自动配置Redis原理 一.自动配置redis RedisAutoConfigur ...

  8. GitChat · 架构 | 大规模私有云产品自动升级的架构选型和实战

    GitChat 作者:冰尘 原文: 大规模私有云产品自动升级的架构选型和实战 关注微信公众号:GitChat 技术杂谈 ,一本正经的讲技术 一.项目背景概述 对于云计算,每个人都有自己的定义,有按SA ...

  9. C#实现软件自动升级

    winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,本文结合实际情况,通过软件实现自动升级,弥补了这一缺陷,有较好的参考价值. 由于程序在运行 ...

最新文章

  1. 系统设计与架构笔记:ETL工具开发和设计的建议
  2. 随机数生成算法-二谈
  3. copy和mutablecpy区别
  4. 修改wamp默认网站目录
  5. class字节码文件中的常量池结构详解
  6. VB6转换C#2010函数替换
  7. [Spring5]IOC容器_Bean管理注解方式_组件扫描配置细节
  8. Java应用结构规范
  9. swoole php input,介绍swoole异步群发模板消息
  10. Windows Phone开发(33):路径之其它Geometry 转:http://blog.csdn.net/tcjiaan/article/details/7483835...
  11. centos下nginx bind() to 0.0.0.0:8090 failed
  12. 大漠插件常见问题汇总
  13. 错过等一年!物流与交通的先锋碰撞,点击进入这场大佬云集的学术盛宴
  14. nSMS-企业级短信中间件介绍
  15. 这些各行各业优秀的ppt模板推荐给大家
  16. 用ECS做HexMap:鼠标点击六边形单元涂色
  17. 金山现任CEO张宏江将退休 西山居CEO继任
  18. 《C游记》 第二章 - 初识分支句 循环助本心(壹)
  19. 高等数学---行列式,矩阵
  20. kubernetes使用Træfik代理服务

热门文章

  1. Linux服务器多网卡多网关配置解决方案
  2. AndroidStudio实现第三方QQ分享,空间分享
  3. jmeter的响应断言的使用
  4. wegt 提示 scheme missing
  5. java中 byte 取值范围_java中为什么byte的取值范围是-128到+127
  6. 我的世界自动开关服务器,我的世界自动重启脚本方法_我的世界如何让服务器自动重启_游戏堡...
  7. linux ssh攻击 服务器自动重启
  8. Python绘制气泡图示例
  9. Vue2组件封装 Vue组件封装
  10. cut最后几位 shell_linux的cut命令用法总结