如何制作自動更新程序?

原文出自: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?String)?As?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?Object,?ByVal?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.Object,?ByVal?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.Object,?ByVal?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.Object,?ByVal?e?As?System.EventArgs)?Handles?MyBase.Load??
  121. ????????LoadUpdateFile()??
  122. ????????DownloadNextFile()??
  123. ????End?Sub??
  124. ??
  125. End?Class??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458764.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458764.shtml
英文地址,請注明出處:http://en.pswp.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…