如何制作自动更新程序?

原文出自:http://blog.csdn.net/metaphysis/article/details/18866631


如何制作自动更新程序?

[版权所有 邱秋 2014 metaphysis@yeah.net, 转载请注明出处]

最近为单位写了一个C/S结构的软件,这个软件是工作在单位的局域网内的。为了减轻为程序进行升级的工作量,需要解决程序自动更新的问题。那么如何做一个自动更新程序呢?

想了一下,更新程序需要解决以下问题:

(A)它需要知道哪些是需要更新的文件,哪些是不需要的文件;

(B)它需要知道从哪里下载更新文件;

(C) 它需要将更新的文件下载下来,并将旧的文件替换掉,将不再需要的文件删除掉;

(D)它需要能够在更新完毕后自动重新启动程序以便用户继续使用;

问题(A)可以通过版本控制的方法来解决。具体方法是为程序所使用的文件都设定一个版本号,所有文件的版本号都记录在一个 XML 文件中,当升级时,检查最新程序的版本控制文件和当前的版本控制文件,当版本号较大时,则表示该文件需要更新。最新的版本控制文件可以放在一个匿名 FTP 上以便程序下载下来和本地的版本控制文件进行比对。如果一个文件不再需要了,则将该文件的版本信息从最新的版本控制文件中删除,通过对比控制文件,就知道该文件不再需要了,可以将之删除。由于我写的程序除主程序外,其他组件都不会发生太多改动,所以我使用了如下的方式来表示一个文件的版本信息:

[vb] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <AutoUpdater>  
  3.   <Updater>  
  4.     <UpdateUrl>ftp://192.168.1.24/update/</UpdateUrl>  
  5.     <MainVersion>1.1.102.0</MainVersion>  
  6.     <LastUpdateTime>2014-01-27</LastUpdateTime>  
  7.     <UpdateDescription>自动更新程序</UpdateDescription>  
  8.   </Updater>  
  9.   <UpdateFileList>  
  10.     <UpdateFile Version="2.2.5.0" Name="AForge.dll" />  
  11.     <UpdateFile Version="2.2.5.0" Name="AForge.Video.DirectShow.dll" />  
  12.     <UpdateFile Version="2.2.5.0" Name="AForge.Video.dll" />  
  13.     <UpdateFile Version="1.0.100.0" Name="USBCleaner.exe" />  
  14.     <UpdateFile Version="1.0.100.0" Name="USBViewer.exe" />  
  15.   </UpdateFileList>  
  16. </AutoUpdater>  

UpdateUrl 告诉程序要从什么地方下载最新的版本控制文件和更新文件,这里我使用了 FTP 的方式,这样简单一些,我将版本控制文件和最新的程序文件都放在了 ftp://192.168.1.24/update/ 下。MainVersion 表示程序的版本,用来确定是否需要进行升级。LastUpdateTime 表示程序最后的更新时间。UpdateDescription 表示更新程序的描述。UpdateFile 则表示程序中的每一个文件条目,Version 表示其版本,Name 表示相对于程序根目录的文件路径名,如果文件是在根目录下面,则直接是文件名,如果是在子目录下,则在前面加上相应的子目录。

有了这个版本控制文件,问题(B)也解决了,因为从指定的地址下载即可。

问题(C)可以通过比对版本控制文件,确定需要下载的文件和不再需要的文件。然后通过 WebClient 类来下载需要的文件。

问题(D)可以这样解决,主程序先检查是否有升级,如果有升级,则将旧的更新程序再复制一份,启动复制的更新程序,并启动它来下载更新文件,这样的话,就可以解决更新更新程序本身的问题,因为将新的更新程序下载来后,可以直接覆盖掉原始的更新程序而不会产生文件正在使用无法更新的问题,因为运行的是旧的更新程序的副本,在全部更新完毕后,主程序中可以加一段代码检测是否有更新副本产生,只要有就将它删除即可。

想清楚了这些问题,就是具体代码实现了,以下把版本文件解析的代码和更新下载文件的代码贴出来,整个更新模块也提供了下载,供有兴趣的朋友参考使用。下载链接:http://download.csdn.net/detail/metaphysis/6891593。

[vb] view plaincopy在CODE上查看代码片派生到我的代码片
  1. XmlVersionConfigFile.vb  
  2.   
  3. Imports System.Xml  
  4. Imports System.Xml.Linq  
  5.   
  6. Public Class XmlVersionConfigFile  
  7.   
  8.     Public Property UpdateUrl As String = String.Empty  
  9.     Public Property MainVersion As Version = Version.Parse("0.0.0.0")  
  10.     Public Property LastUpdateTime As Date = DateTimePicker.MinimumDateTime  
  11.     Public Property UpdateDescription As String = String.Empty  
  12.     Public Property UpdateFileList As Dictionary(Of String, Version) = Nothing  
  13.   
  14.     Public Sub New(ByVal fileContent As String)  
  15.         ParseXmlVersionFile(fileContent)  
  16.     End Sub  
  17.   
  18.     Private Function ParseXmlVersionFile(ByVal fileContent As StringAs Boolean  
  19.         Dim xdoc As XDocument = Nothing  
  20.         Try  
  21.             xdoc = XDocument.Parse(fileContent)  
  22.         Catch ex As Exception  
  23.             Return False  
  24.         End Try  
  25.   
  26.         Me.UpdateUrl = xdoc.Element("AutoUpdater").Element("Updater").Element("UpdateUrl").Value  
  27.         Me.MainVersion = Version.Parse(xdoc.Element("AutoUpdater").Element("Updater").Element("MainVersion").Value)  
  28.         Date.TryParse(xdoc.Element("AutoUpdater").Element("Updater").Element("LastUpdateTime").Value, Me.LastUpdateTime)  
  29.         Me.UpdateDescription = xdoc.Element("AutoUpdater").Element("Updater").Element("UpdateDescription").Value  
  30.   
  31.         Me.UpdateFileList = New Dictionary(Of String, Version)  
  32.         Dim query = From UpdateFile In xdoc.Descendants("UpdateFile"Select UpdateFile  
  33.         For Each fileInfo As XElement In query  
  34.             Me.UpdateFileList.Add(fileInfo.Attribute("Name").Value.ToLower, Version.Parse(fileInfo.Attribute("Version").Value))  
  35.         Next  
  36.   
  37.         Return True  
  38.     End Function  
  39. End Class  
[vb] view plaincopy在CODE上查看代码片派生到我的代码片
  1. UpdatingForm.vb  
  2.   
  3. Imports System.IO  
  4.   
  5. Public Class UpdatingForm  
  6.   
  7.     Public Property LocalVersionConfig As XmlVersionConfigFile = Nothing  
  8.     Public Property ServerVersionConfig As XmlVersionConfigFile = Nothing  
  9.   
  10.     Private WithEvents webClient As New System.Net.WebClient  
  11.   
  12.     Private _downloadIndex As Integer  
  13.     Private _localConfigFileName As String = "version.xml"  
  14.     Private _localXmlFilePath As String = Path.Combine(Application.StartupPath, _localConfigFileName)  
  15.     Private _updateUrl As String = String.Empty  
  16.     Private _deleteFileList As New List(Of String)  
  17.   
  18.     Private Sub webClient_DownloadFileCompleted(ByVal sender As ObjectByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles webClient.DownloadFileCompleted  
  19.         Me.lvwFile.Items(_downloadIndex).ImageIndex = 2  
  20.   
  21.         lblSinglePercent.Text = "0%"  
  22.         prbSingle.Value = 0  
  23.   
  24.         DownloadNextFile()  
  25.     End Sub  
  26.   
  27.     Private Sub webClient_DownloadProgressChanged(ByVal sender As System.ObjectByVal e As System.Net.DownloadProgressChangedEventArgs) Handles webClient.DownloadProgressChanged  
  28.         Dim currentPercent As String = e.ProgressPercentage & "%"  
  29.         If currentPercent <> Me.lvwFile.Items(_downloadIndex).SubItems(3).Text Then  
  30.             Me.lvwFile.Items(_downloadIndex).SubItems(3).Text = currentPercent  
  31.             prbSingle.Value = e.ProgressPercentage  
  32.             lblSinglePercent.Text = currentPercent  
  33.             prbAll.Value = Int((_downloadIndex + 1) / Me.lvwFile.Items.Count * 100)  
  34.             lblAllPercent.Text = prbAll.Value & "%"  
  35.         End If  
  36.     End Sub  
  37.   
  38.     Private Sub btnQuit_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles btnQuit.Click  
  39.         Me.Close()  
  40.     End Sub  
  41.   
  42.     Private Sub DownloadNextFile()  
  43.         If _downloadIndex < (lvwFile.Items.Count - 1) Then  
  44.   
  45.             _downloadIndex += 1  
  46.   
  47.             lvwFile.Items(_downloadIndex).ImageIndex = 1  
  48.   
  49.             Try  
  50.                 Dim destPath As String = IO.Path.Combine(Application.StartupPath, lvwFile.Items(_downloadIndex).SubItems(1).Text)  
  51.                 File.Delete(destPath)  
  52.                 webClient.DownloadFileAsync(New Uri(_updateUrl & lvwFile.Items(_downloadIndex).SubItems(1).Text), destPath)  
  53.             Catch ex As Exception  
  54.                 Me.lvwFile.Items(_downloadIndex).ImageIndex = 3  
  55.                 MsgBox("下载文件发生错误,更新失败。错误原因: " & ex.Message, MsgBoxStyle.Critical, "错误")  
  56.                 Me.Close()  
  57.             End Try  
  58.         Else  
  59.             UpdateFileCompleted()  
  60.         End If  
  61.     End Sub  
  62.   
  63.     Private Sub UpdateFileCompleted()  
  64.         ' 更新显示信息。  
  65.         prbSingle.Value = prbSingle.Maximum  
  66.         lblSinglePercent.Text = "100%"  
  67.         lblAllPercent.Text = "100%"  
  68.   
  69.         ' 删除不需要的文件。  
  70.         For Each f As String In _deleteFileList  
  71.             Try  
  72.                 File.Delete(Path.Combine(Application.StartupPath, f))  
  73.             Catch ex As Exception  
  74.                 '  
  75.             End Try  
  76.         Next  
  77.   
  78.         Me.btnQuit.Enabled = True  
  79.         Process.Start(IO.Path.Combine(Application.StartupPath, "szpt.exe"))  
  80.         Me.Close()  
  81.     End Sub  
  82.   
  83.     Private Sub LoadUpdateFile()  
  84.         _updateUrl = Me.ServerVersionConfig.UpdateUrl  
  85.   
  86.         ' 查找客户端需要更新的文件和需要删除的文件。  
  87.         For Each p As KeyValuePair(Of String, Version) In Me.LocalVersionConfig.UpdateFileList  
  88.             If Me.ServerVersionConfig.UpdateFileList.ContainsKey(p.Key) Then  
  89.                 If Me.ServerVersionConfig.UpdateFileList(p.Key) > Me.LocalVersionConfig.UpdateFileList(p.Key) Then  
  90.                     Dim item As ListViewItem = Me.lvwFile.Items.Add(String.Empty, 0)  
  91.                     item.SubItems.Add(p.Key)  
  92.                     item.SubItems.Add(Me.ServerVersionConfig.UpdateFileList(p.Key).ToString)  
  93.                     item.SubItems.Add(String.Empty)  
  94.                 End If  
  95.             Else  
  96.                 _deleteFileList.Add(p.Key)  
  97.             End If  
  98.         Next  
  99.   
  100.         ' 查找服务器端新增需要下载的文件。  
  101.         For Each p As KeyValuePair(Of String, Version) In Me.ServerVersionConfig.UpdateFileList  
  102.             If Me.LocalVersionConfig.UpdateFileList.ContainsKey(p.Key) = False Then  
  103.                 Dim item As ListViewItem = Me.lvwFile.Items.Add(String.Empty, 0)  
  104.                 item.SubItems.Add(p.Key)  
  105.                 item.SubItems.Add(p.Value.ToString)  
  106.                 item.SubItems.Add(String.Empty)  
  107.             End If  
  108.         Next  
  109.   
  110.         ' 版本控制文件为必须下载文件。  
  111.         Dim itemVersion As ListViewItem = Me.lvwFile.Items.Add(String.Empty, 0)  
  112.         itemVersion.SubItems.Add("version.xml")  
  113.         itemVersion.SubItems.Add(Me.ServerVersionConfig.MainVersion.ToString)  
  114.         itemVersion.SubItems.Add(String.Empty)  
  115.   
  116.         ' 设置当前下载的文件序数。  
  117.         _downloadIndex = -1  
  118.     End Sub  
  119.   
  120.     Private Sub UpdatingForm_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load  
  121.         LoadUpdateFile()  
  122.         DownloadNextFile()  
  123.     End Sub  
  124.   
  125. End Class  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

包含JS交互的混淆出错

2019独角兽企业重金招聘Python工程师标准>>> 小上司离职&#xff0c;我接手他负责的项目&#xff0c;进行版本更新的时候&#xff0c;在生成jar包测试的时候&#xff0c;点击按钮没有反应&#xff0c;页面是webview&#xff0c;按钮则是与js交互&#xff0c;logcat打…

计算机常用代码大全,常用电脑命令大全【图文】

导语 &#xff1a;电脑&#xff0c;这个在前几年貌似还离我们非常遥远的词汇&#xff0c;现在随着信息化社会的不断发展&#xff0c;已经走进了我们的千家万户。现在每一家新 装修 &#xff0c;它都作为一种必备的家用电器来使用。由此可见电脑对我们 现代 人的重要性。但电脑毕…

细数技术指标-[转载]

技术指标类别庞杂&#xff0c;要一一学全&#xff0c;基本不可能&#xff0c;也没有这个必要。我们只要掌握几个常用的指标&#xff0c;了解它们的原理&#xff0c;从而举一反三&#xff0c;就足够了。其实任何一种技术指标都是从形态、价格、量、时间这四项出发的&#xff0c;…

[javaSE] 看博客学习java并发编程

共享性 多线程操作同一个数据&#xff0c;产生线程安全问题 新建一个类ShareData 设计一个int 型的成员变量count 设计一个成员方法addCount()&#xff0c;把count变量 在main函数中开启多个线程操作这个成员变量&#xff0c;在main函数里 获取ShareData对象&#xff0c;new 出…

GetProcAddress() LoadLibrary() DLL

GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。 函数原型&#xff1a; FARPROC GetProcAddress( HMODULE hModule, // DLL模块句柄 LPCSTR lpProcName // 函数名 ); 参数&#xff1a; hModule [in] 包含此函数的DLL模块的句柄。LoadLibrary、AfxLoadLibrary…

小学计算机输入法主题教研设计,《拼音输入法》教学设计.doc

10.拼音输入法【教材分析】《拼音输入法》是浙江摄影出版社出版的新版《小学信息技术》三年级下册第三单元第10课。信息技术是一门技能课&#xff0c;学以致用是技能课的教学目的&#xff0c;相对来说&#xff0c;在小学生的学习和生活中&#xff0c;用到这项技能的地方还比较少…

图论测试题(一)第一题:longest

第一题&#xff1a;longest 乌托邦有n个城市&#xff0c;某些城市之间有公路连接。任意两个城市都可以通过公路直接或者间接到达&#xff0c;并且任意两个城市之间有且仅有一条路径&#xff08;What does this imply? A tree!&#xff09;。 每条公路都有自己的长度&#xff0…

RTC实时时钟驱动

RTC&#xff08;Real-Time Clock)实时时钟为操作系统提供了一个可靠的时间&#xff0c;并且在断电的情况下&#xff0c;RTC实时时钟也可以通过电池供电&#xff0c;一直运行下去。 RTC通过STRB/LDRB这两个ARM指令向CPU传送8位数据&#xff08;BCD码&#xff09;。数据包括秒&am…

Compass样式重置

1. 全局样式重置 main.scss文件插入 import "compass/reset"; 对应的生成css为 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, sa…

计算机表格复制粘贴后不变,excel表格复制粘贴后格式不变

Excel使用过程中经常需要将一个表格内容复制粘贴到其他表格中去。如果原始表格设置了行高和列宽&#xff0c;选中要复制的区域复制后&#xff0c;当在其他表格选择一个单元格进行粘贴时&#xff0c;行高和列宽就都变了。下面介绍excel表格复制粘贴后格式不变的操作方法。excel表…

C++ Primer章课后编程问题

1、代码#include<iostream> int main() {using namespace std;int num1;int num2;int total0;cout << "请输入開始数字\n";cin >> num1;cout << "请输入结束数字\n";cin >> num2;for (num1; num1<num2; num1)total num1…

vps搭建网站服务器,vps如何架设网站服务器

弹性云服务器 ECS弹性云服务器(Elastic Cloud Server)是一种可随时自助获取、可弹性伸缩的云服务器&#xff0c;帮助用户打造可靠、安全、灵活、高效的应用环境&#xff0c;确保服务持久稳定运行&#xff0c;提升运维效率三年低至5折&#xff0c;多种配置可选了解详情手工部署D…

vs 常见问题汇总

vs添加对dll的引用 我们在使用vs进行开发调试的时候经常会遇到一个问题&#xff0c;就是当我们的主工程引用到其他工程更新的dll&#xff08;我们经常采用copy到工程目录的方法&#xff09;、亦或者当我们的多个工程引用到同一个dll文件的时候&#xff0c;我们怎么来配置&#…

斯柯达柯珞克显示服务器错误,斯柯达柯珞克原来还有四驱的版本,不信你看!...

▶有望推出四驱版本▶专利图已经曝光▶外观没有变化斯柯达柯珞克大家应该不会特别陌生&#xff0c;虽然它在前两个月才正式上市&#xff0c;不过作为一款合资的紧凑型SUV来说&#xff0c;它的关注度还是不错的。销量上&#xff0c;4月份交出了2668辆的成绩&#xff0c;虽然还不…

javascript实例——鼠标特效篇(包含2个实例)

鼠标是现在电脑的基本配置之一&#xff0c;也是最常用的输入命令的工具之一。本文将将一些与鼠标有关系的特效。 1、跟随鼠标移动的彩色星星 如题&#xff0c;会根据鼠标的移动而移动&#xff0c;并在鼠标周围随机来回移动&#xff0c;让人感觉在放大缩小。根据书上的代码做了一…

Perforce使用指南_forP4V

第一章 前言 Perforce SCM System是一款构建于可伸缩客户/服务器结构之上的软件配置管理工具。仅仅应用 TCP/IP&#xff0c;开发人员就能够通过多种Perforce客户端&#xff08;几种平台的GUI、WEB、或命令行&#xff09;访问 Perforce服务器。Perforce能够被快速和容易地部署…

sql语句示例

sql语句示例&#xff1a; 选区指定的列 select 图书编号,图书名称 from 图书查询全部信息 select * from 图书查询信息之后更改所获得的列的名称 select 姓名 as 用户名, 电话 as 联系电话 from 用户也可以这样 select 用户名姓名,联系电话电话 from 用户对某些列进行计筭后在显…

曙光服务器优势,5大核心优势 探秘曙光Cloudview三大平台

1Cloudview1.5核心优势对于云计算而言&#xff0c;国产厂商也有着自己独到的云方案。曙光Cloudview云计算操作系统采用新一代云计算中心的全新的管理模型&#xff0c;充分考虑云计算中心的资源分配、业务运行和运维服务等各种管理要素&#xff0c;实现云计算中心的软硬件平台资…

Centos 下面升级系统内核(转)

1、导入public key 1rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org2、安装ELRepo到CentOS 6.6中 1rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm3、安装长期支持版本 1yum --enablerepoelrepo-kernel install kernel-lt -y4、编辑g…

Mantle--国外程序员最常用的iOS模型字典转换框架

Mantle简介 Mantle是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架。 Mantle能做什么 Mantle可以轻松把JSON数据、字典&#xff08;Dictionary&#xff09;和模型&#xff08;即Objective对象&#xff09;之间的相互转换&#xff0c;支持自定义映射&#xff0c…