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

如何制作自动更新程序?

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

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

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

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

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

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

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

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

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

如何制作自动更新程序?相关推荐

  1. C#软件自动更新程序

    2019独角兽企业重金招聘Python工程师标准>>> 基于C#实现的软件自动更新程序,之前在网上搜集了两款软件自动更新程序,在实际应用中,对部分BUG进行修复,添加+完善一些功能. ...

  2. C# WINFORM的自动更新程序

    自动更新程序AutoUpdate.exe https://git.oschina.net/victor596jm/AutoUpdate.git 1.获取源码 http://git.oschina.ne ...

  3. 投票脚本软件制作,自动投票程序

    投票脚本制作,自动投票程序 第三方投票自动化刷投票脚本代码 主要内容 分析网站 表单提交 正在构建代理IP池 网站的分析因为每个网站需要提交的信息不一样,首先我们需要对目标网站进行分析,找出它们的表单 ...

  4. python自动更新程序

    简介 windows 自动更新程序 最近用python给开发了一个windows监控软件,用于监控电脑的运行情况,更新电脑软件.由于有几十电脑,一台一台手动更新就不太靠谱了,于是就开发了一个自动更新软 ...

  5. 【原创】自动更新程序2--更新程序的主窗体(技术:spring.net+三层架构+webservice+IrisSkin2换肤)...

    上篇文章主要介绍了webservice的部署以及主要的代码,下面给大家贴上主程序的代码,并简单的讲解.主程序判断是否有更新时通过主程序目录下有一个update.ini文件内的version是否有变化, ...

  6. 简单的自动更新程序实现

    本文将演示一种桌面程序自动更新方案,其步骤比较多,但原理非常简单,通用性尚可,对于小型应用来说,直接拿去就可以用了. 原理 服务器端的结构是这样的: 其工作原理如下: Update.asmx仅提供一个 ...

  7. 的序号数据是什么_Excel技巧—一劳永逸制作自动更新序号

    点赞再看,养成习惯: 不登高山,不知天之高也. 平时在制作Excel表格的时候,为了数据的查阅统计,我们经常会为数据加上需要,这样在统计数据量,查看某条记录的时候就会很方便. 今天小编就带大家来看看怎 ...

  8. 使用Advanced Installer为LabVIEW应用(exe)制作升级更新程序(updater)

    0.前言 上一篇博文:<使用Advanced Installer为LabVIEW生成的exe制作安装程序>讲了弃用LabVIEW自带的安装程序部署,转而使用Advanced Install ...

  9. 艾伟_转载:简单的自动更新程序实现

    本文将演示一种桌面程序自动更新方案,其步骤比较多,但原理非常简单,通用性尚可,对于小型应用来说,直接拿去就可以用了. 原理 服务器端的结构是这样的: 其工作原理如下: Update.asmx仅提供一个 ...

最新文章

  1. 户外生活--西湖林至千军台
  2. OpenGL着色器基础
  3. Python之路(第二十一篇) re模块
  4. 源码|批量执行invokeAll()多选一invokeAny()
  5. Eclipse 导出
  6. python爬虫框架Scrapy采集数据,并制作词云图分析!
  7. Android开发之自定义UI组件和属性
  8. 怎样使用PDFlib显示简体中文输出中文而不出现空白说明附源码
  9. 论文中c语言程序的格式,毕业论文程序代码格式_毕业论文范本_论文的标准格式模板...
  10. ImageView实现圆形头像效果
  11. devil may cry 4 android apk,Devil May Cry
  12. C语言:输入10个整数,找出其中绝对值最小的数
  13. 外卖点餐管理系统源码
  14. 心跳检测,用oob实现
  15. vue和 element ui下载到本地后引入
  16. 装系统需不需要格式化系统盘?别再被这些说法骗了!
  17. Linux的任督二脉之内存管理线上微信群直播报名(2018.1.29-2.2)
  18. 解决网页文字无法复制
  19. 关于CLASS , SEL, IMP的说明
  20. Android开发中长度单位简介

热门文章

  1. TCP/IP协议族 详解(TCP/IP四层模型、OSI七层模型)
  2. Shell 字符串截取
  3. Nginx安装手册(摘自入云龙老师教案,亲测可用)
  4. 【算法】QuickSort
  5. Magento--修改已存在的订单的运费
  6. uva 10716 Evil Straw Warts Live
  7. [每日一题jQuery] jQuery选择器总结:进一步过滤、同级操作、后代操作
  8. 用一个简单的例子来演绎事件委托
  9. 【POJ】2065 SETI
  10. Gnuplot 简单使用