如何制作自动更新程序?

原文出自: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;…

图论测试题(一)第一题: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…

计算机表格复制粘贴后不变,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…

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能够被快速和容易地部署…

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

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

直连测速服务器异常,求证! 网件R7800, Speedtest测速的怪现象,200M宽带+R7800者进...

本帖最后由 毛毛雨 于 2017-11-18 18:50 编辑宽带是联通FTTH 200M&#xff0c;标准千兆网线&#xff0c;千兆网卡。问题前的插曲&#xff1a;R7800刚到手&#xff0c;就迫不及待的换上了&#xff0c;结果&#xff0c;无论是路由器内置Speedtest册数&#xff0c;还是电脑端的Spe…

iOS socket

为什么80%的码农都做不了架构师&#xff1f;>>> #import "ViewController.h"interface ViewController ()<NSStreamDelegate,UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>{NSInputStream *_inputStream;//对应输入流NSOutputS…

Macosx 安装 ionic 成功教程

2019独角兽企业重金招聘Python工程师标准>>> 一、首先介绍一下ionic ionic是一个用来开发混合手机应用的&#xff0c;开源的&#xff0c;免费的代码库。可以优化html、css和js的性能&#xff0c;构建高效的应用程序&#xff0c;而且还可以用于构建Sass和AngularJS的…

mac显示无法连接adobe服务器,Mac安装Adobe软件,如遇Error提示解决方法

Mac10.15.3 安装Adobe Photoshop 2020的时候一直提示Error错误The installation cannot continue as the installer file may be damaged. Download the installer file again.看到这种问题&#xff0c;一般第一想法就是安装包损坏了&#xff0c;本能的会再下载一遍甚至多遍&am…

Grovvy初识

1.Groovy和Java对比 Groovy的松散的语法允许省略分号和修饰符除非另行指定&#xff0c;Grovvy的所有内容都为publicGrovvy允许定义简单脚本&#xff0c;同时无需定义正规的class对象Grovvy在普通的常用java对象上增加了一些独特的方法和快捷方式&#xff0c;使得他们更容易使用…

一个服务器多个网站多个域名,多个域名一个服务器吗

多个域名一个服务器吗 内容精选换一换PAS(Primary Application Server)&#xff1a;主应用服务器。AAS(Additional Application Server)&#xff1a;扩展应用服务器。ASCS(ABAP Central Services)&#xff1a;SAP应用核心服务&#xff0c;是SAP应用的一个核心控件&#xff0c;包…

Spring源码解析——如何阅读源码

阅读目录 下面看一下如何使用jar包以及源码的source包  下面给出一个简单的spring样例  如何阅读源码最近没什么实质性的工作&#xff0c;正好有点时间&#xff0c;就想学学别人的代码。也看过一点源码&#xff0c;算是有了点阅读的经验&#xff0c;于是下定决心看下spring…

ajax当页post请求,tag落地页--通过ajax-post请求数据

查询所有tag及其对应跳转链接$tags get_tags(array(get>all));$output . ;if($tags) {foreach ($tags as $tag):$output . . $tag->name .;endforeach;} else {_e(No tags created., text-domain);}$output . ;echo $output;交互tag查询image场景如下&#xff0c;通过页…