• Winform 自动升级程序


    抽时间整理下升级这块的功能,并封装一个升级工具包。

    作为winform 程序员都有一个C/S端程序绕不过的问题。那就是如何升级程序?

    程序升级两种1.启动时强制更新 2.自动、手动获取更新,并确认是否升级。

    今天咱们介绍,自动或者手动更新功能。

           首先思考如何升级? 升级肯定要有一个新的升级文件包,还有一个本地版本和服务器版本号,因为这样才能对比是否升级。

           看下下面的升级提示:

     等待上面的升级下载程序完毕即可。会自动替换主程序,并启动主程序。

    设计思路:我绘制了一张图可以从图中看。

     1. 主程序开始升级,会检查是否有升级器有就启动下载,没有就去先下载升级器

     2. 启动升级器,下载文件,下载后解压替换主程序。 并启动主程序。 

    下载器的一些代码:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Configuration;
    5. using System.Data;
    6. using System.Diagnostics;
    7. using System.Drawing;
    8. using System.IO;
    9. using System.Linq;
    10. using System.Text;
    11. using System.Threading;
    12. using System.Windows.Forms;
    13. namespace AutoUpdate
    14. {
    15. public partial class FrmMain : Form
    16. {
    17. public FrmMain()
    18. {
    19. InitializeComponent();
    20. }
    21. string Rootpath = Environment.CurrentDirectory;
    22. ///
    23. /// 本地存储目录
    24. ///
    25. string ZipFilePath = Common.FilePathConfig.DownZIPPath;
    26. ///
    27. /// 本地解压目录
    28. ///
    29. string UnFilePath = Common.FilePathConfig.UnDownZIPPath;
    30. ///
    31. /// 开始升级程序客户端 author:huochengyan
    32. ///
    33. ///
    34. ///
    35. private void button1_Start_Click(object sender, EventArgs e)
    36. {
    37. timer1.Enabled = true;
    38. Thread th = new Thread(StartUpdate);
    39. th.IsBackground = true;
    40. th.Start();
    41. }
    42. ///
    43. /// 开始下载文件 升级
    44. ///
    45. private void StartUpdate()
    46. {
    47. bool result = Common.HttpHelper.HttpDownload(Common.FilePathConfig.DownZIPUrl, ZipFilePath, this.progressBar1, this.label2_tishi);
    48. timer1.Enabled = false;
    49. if (result)
    50. {
    51. RefThisForm("下载成功!");
    52. Thread.Sleep(100);
    53. RefThisForm("正在解压,请稍后");
    54. if (!Directory.Exists(UnFilePath))
    55. Directory.CreateDirectory(UnFilePath);
    56. //UnFilePath = new FileInfo(ZipFilePath).DirectoryName;
    57. string reusult = Common.ZIPHelper.UnZipFile(ZipFilePath,UnFilePath);
    58. if (reusult != "")
    59. {
    60. RefThisForm("解压成功!");
    61. CheckUnZIPFile(reusult);
    62. }
    63. else
    64. {
    65. RefThisForm("解压失败!压缩包路径:" + ZipFilePath);
    66. }
    67. }
    68. else
    69. {
    70. MsgShow("下载失败!");
    71. }
    72. }
    73. private void FrmMain_Load(object sender, EventArgs e)
    74. {
    75. InitConfig();
    76. FrmMain.CheckForIllegalCrossThreadCalls = false;
    77. //删除陈旧的历史下载记录ZIP信息
    78. try
    79. {
    80. File.Delete(ZipFilePath);
    81. }
    82. catch (Exception ex)
    83. {
    84. }
    85. //检查下载器文件的dll
    86. button1_Start_Click(null, null);
    87. }
    88. private void CheckFile()
    89. {
    90. string UnZipdllPath = Rootpath + "/ICSharpCode.SharpZipLib.dll";
    91. if (!File.Exists(UnZipdllPath))
    92. {
    93. MessageBox.Show("下载器文件丢失:ICSharpCode.SharpZipLib.dll");
    94. }
    95. }
    96. private void InitConfig() {
    97. try
    98. {
    99. Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    100. Common.FilePathConfig.DownZIPUrl = config.AppSettings.Settings["softURL"].Value;
    101. }
    102. catch (Exception ex)
    103. {
    104. MessageBox.Show("读取配置失败!" + ex.ToString());
    105. }
    106. }
    107. ///
    108. /// 检查文件 解压
    109. ///
    110. ///
    111. private void CheckUnZIPFile(string UnZipFileDirPath)
    112. {
    113. string mainexe = UnZipFileDirPath + "/LongDeTools.exe";
    114. Directory.SetCurrentDirectory(Directory.GetParent(UnZipFileDirPath).FullName);
    115. string OldFolder = Directory.GetCurrentDirectory();
    116. if (!File.Exists(mainexe))
    117. {
    118. MessageBox.Show("未能找到主程序:" + mainexe);
    119. return;
    120. }
    121. else {
    122. //覆盖源目录文件
    123. // string result=Common.FileHelper.CopyFolder(OldFolder,UnZipFileDirPath);
    124. //MessageBox.Show("请确认开始替换原始文件!");
    125. RefThisForm("安装中..."); //RefThisForm("替换原始主程序中。。。。");
    126. bool result1=Common.FileHelper.CopyOldLabFilesToNewLab(UnZipFileDirPath,OldFolder,0);
    127. if (result1)
    128. {
    129. RefThisForm("安装中..."); //RefThisForm("替换原始程序完毕。。。。");
    130. //清空解压的文件
    131. FileInfo fileinfo = new FileInfo(UnZipFileDirPath);
    132. try
    133. {
    134. if (Directory.Exists(fileinfo.FullName))
    135. {
    136. // MessageBox.Show("要删除的文件目录:" + fileinfo.FullName);
    137. Common.FileHelper.DelectDir(fileinfo.FullName);
    138. Common.FileHelper.DelectDir(Common.FilePathConfig.UnDownZIPPath);
    139. GC.Collect();
    140. }
    141. }
    142. catch (Exception ex)
    143. {
    144. MsgShow("清理下载文件垃圾失败!"+ex.ToString());
    145. }
    146. }
    147. else
    148. {
    149. MsgShow("升级失败!");
    150. }
    151. }
    152. //2. 启动新下载的程序
    153. StartNewSystem();
    154. GC.Collect();
    155. }
    156. ///
    157. /// 启动最新下载的程序
    158. ///
    159. private void StartNewSystem()
    160. {
    161. //string path = Environment.CurrentDirectory;
    162. //Directory.SetCurrentDirectory(Directory.GetParent(path).FullName);
    163. //path = Directory.GetCurrentDirectory();
    164. //string mainexe = path + "/LongDeTools.exe";
    165. string path=System.Windows.Forms.Application.StartupPath;
    166. string mainexe = "";
    167. if (Directory.Exists(path)) {
    168. mainexe = Directory.GetParent(path)+"/" + "LongDeTools.exe";
    169. }
    170. if (File.Exists(mainexe))
    171. {
    172. Process.Start(mainexe);
    173. RefThisForm("升级完成");
    174. MessageBox.Show("升级到最新版本!!!");
    175. this.Close();
    176. }
    177. else {
    178. MsgShow("要启动的文件不存在!!!"+mainexe);
    179. }
    180. ///清理下载的文件的缓存垃圾
    181. GC.Collect();
    182. }
    183. private void RefThisForm(string text)
    184. {
    185. this.Text = text;
    186. }
    187. ///
    188. /// 时间 戳 事件
    189. ///
    190. ///
    191. ///
    192. private void timer1_Tick(object sender, EventArgs e)
    193. {
    194. //Console.WriteLine("时间timer\r\n"+DateTime.Now.ToString()+"\r\n");
    195. label2_tishi.Text = progressBar1.Value/1048576+"M/"+ progressBar1.Maximum/ 1048576 + "M";
    196. if(progressBar1.Value== progressBar1.Maximum)
    197. label2_tishi.Text= progressBar1.Maximum / 1048576 + "M/" + progressBar1.Maximum / 1048576 + "M";
    198. }
    199. private void MsgShow(string msg) {
    200. MessageBox.Show(msg);
    201. }
    202. private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    203. {
    204. FrmSetServer frm = new FrmSetServer();
    205. frm.ShowDialog();
    206. }
    207. }
    208. }

     

    1. using ICSharpCode.SharpZipLib.Checksums;
    2. using ICSharpCode.SharpZipLib.Zip;
    3. using System;
    4. using System.Collections.Generic;
    5. using System.IO;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Windows.Forms;
    9. namespace AutoUpdate.Common
    10. {
    11. ///
    12. /// 适用与ZIP压缩
    13. ///
    14. public class ZIPHelper
    15. {
    16. #region 压缩
    17. ///
    18. /// 递归压缩文件夹的内部方法
    19. ///
    20. /// 要压缩的文件夹路径
    21. /// 压缩输出流
    22. /// 此文件夹的上级文件夹
    23. ///
    24. private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
    25. {
    26. bool result = true;
    27. string[] folders, files;
    28. ZipEntry ent = null;
    29. FileStream fs = null;
    30. Crc32 crc = new Crc32();
    31. try
    32. {
    33. ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
    34. zipStream.PutNextEntry(ent);
    35. zipStream.Flush();
    36. files = Directory.GetFiles(folderToZip);
    37. foreach (string file in files)
    38. {
    39. fs = File.OpenRead(file);
    40. byte[] buffer = new byte[fs.Length];
    41. fs.Read(buffer, 0, buffer.Length);
    42. ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
    43. ent.DateTime = DateTime.Now;
    44. ent.Size = fs.Length;
    45. fs.Close();
    46. crc.Reset();
    47. crc.Update(buffer);
    48. ent.Crc = crc.Value;
    49. zipStream.PutNextEntry(ent);
    50. zipStream.Write(buffer, 0, buffer.Length);
    51. }
    52. }
    53. catch
    54. {
    55. result = false;
    56. }
    57. finally
    58. {
    59. if (fs != null)
    60. {
    61. fs.Close();
    62. fs.Dispose();
    63. }
    64. if (ent != null)
    65. {
    66. ent = null;
    67. }
    68. GC.Collect();
    69. GC.Collect(1);
    70. }
    71. folders = Directory.GetDirectories(folderToZip);
    72. foreach (string folder in folders)
    73. if (!ZipDirectory(folder, zipStream, folderToZip))
    74. return false;
    75. return result;
    76. }
    77. ///
    78. /// 压缩文件夹
    79. ///
    80. /// 要压缩的文件夹路径
    81. /// 压缩文件完整路径
    82. /// 密码
    83. /// 是否压缩成功
    84. public static bool ZipDirectory(string folderToZip, string zipedFile, string password)
    85. {
    86. bool result = false;
    87. if (!Directory.Exists(folderToZip))
    88. return result;
    89. ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
    90. zipStream.SetLevel(6);
    91. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
    92. result = ZipDirectory(folderToZip, zipStream, "");
    93. zipStream.Finish();
    94. zipStream.Close();
    95. return result;
    96. }
    97. ///
    98. /// 压缩文件夹
    99. ///
    100. /// 要压缩的文件夹路径
    101. /// 压缩文件完整路径
    102. /// 是否压缩成功
    103. public static bool ZipDirectory(string folderToZip, string zipedFile)
    104. {
    105. bool result = ZipDirectory(folderToZip, zipedFile, null);
    106. return result;
    107. }
    108. ///
    109. /// 压缩文件
    110. ///
    111. /// 要压缩的文件全名
    112. /// 压缩后的文件名
    113. /// 密码
    114. /// 压缩结果
    115. public static bool ZipFile(string fileToZip, string zipedFile, string password)
    116. {
    117. bool result = true;
    118. ZipOutputStream zipStream = null;
    119. FileStream fs = null;
    120. ZipEntry ent = null;
    121. if (!File.Exists(fileToZip))
    122. return false;
    123. try
    124. {
    125. fs = File.OpenRead(fileToZip);
    126. byte[] buffer = new byte[fs.Length];
    127. fs.Read(buffer, 0, buffer.Length);
    128. fs.Close();
    129. fs = File.Create(zipedFile);
    130. zipStream = new ZipOutputStream(fs);
    131. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
    132. ent = new ZipEntry(Path.GetFileName(fileToZip));
    133. zipStream.PutNextEntry(ent);
    134. zipStream.SetLevel(6);
    135. zipStream.Write(buffer, 0, buffer.Length);
    136. }
    137. catch
    138. {
    139. result = false;
    140. }
    141. finally
    142. {
    143. if (zipStream != null)
    144. {
    145. zipStream.Finish();
    146. zipStream.Close();
    147. }
    148. if (ent != null)
    149. {
    150. ent = null;
    151. }
    152. if (fs != null)
    153. {
    154. fs.Close();
    155. fs.Dispose();
    156. }
    157. }
    158. GC.Collect();
    159. GC.Collect(1);
    160. return result;
    161. }
    162. ///
    163. /// 压缩文件
    164. ///
    165. /// 要压缩的文件全名
    166. /// 压缩后的文件名
    167. /// 压缩结果
    168. public static bool ZipFile(string fileToZip, string zipedFile)
    169. {
    170. bool result = ZipFile(fileToZip, zipedFile, null);
    171. return result;
    172. }
    173. ///
    174. /// 压缩文件或文件夹
    175. ///
    176. /// 要压缩的路径
    177. /// 压缩后的文件名
    178. /// 密码
    179. /// 压缩结果
    180. public static bool Zip(string fileToZip, string zipedFile, string password)
    181. {
    182. bool result = false;
    183. if (Directory.Exists(fileToZip))
    184. result = ZipDirectory(fileToZip, zipedFile, password);
    185. else if (File.Exists(fileToZip))
    186. result = ZipFile(fileToZip, zipedFile, password);
    187. return result;
    188. }
    189. ///
    190. /// 压缩文件或文件夹
    191. ///
    192. /// 要压缩的路径
    193. /// 压缩后的文件名
    194. /// 压缩结果
    195. public static bool Zip(string fileToZip, string zipedFile)
    196. {
    197. bool result = Zip(fileToZip, zipedFile, null);
    198. return result;
    199. }
    200. #endregion
    201. #region 解压
    202. ///
    203. /// 解压功能(解压压缩文件到指定目录)
    204. ///
    205. /// 待解压的文件
    206. /// 指定解压目标目录
    207. /// 密码
    208. /// 解压结果
    209. public static bool UnZip(string fileToUnZip, string zipedFolder, string password)
    210. {
    211. bool result = true;
    212. FileStream fs = null;
    213. ZipInputStream zipStream = null;
    214. ZipEntry ent = null;
    215. string fileName;
    216. if (!File.Exists(fileToUnZip))
    217. return false;
    218. if (!Directory.Exists(zipedFolder))
    219. Directory.CreateDirectory(zipedFolder);
    220. try
    221. {
    222. zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
    223. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
    224. while ((ent = zipStream.GetNextEntry()) != null)
    225. {
    226. if (!string.IsNullOrEmpty(ent.Name))
    227. {
    228. fileName = Path.Combine(zipedFolder, ent.Name);
    229. fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
    230. if (fileName.EndsWith("\\"))
    231. {
    232. Directory.CreateDirectory(fileName);
    233. continue;
    234. }
    235. fs = File.Create(fileName);
    236. int size = 2048;
    237. byte[] data = new byte[size];
    238. while (true)
    239. {
    240. size = zipStream.Read(data, 0, data.Length);
    241. if (size > 0)
    242. fs.Write(data, 0, data.Length);
    243. else
    244. break;
    245. }
    246. }
    247. }
    248. }
    249. catch
    250. {
    251. result = false;
    252. }
    253. finally
    254. {
    255. if (fs != null)
    256. {
    257. fs.Close();
    258. fs.Dispose();
    259. }
    260. if (zipStream != null)
    261. {
    262. zipStream.Close();
    263. zipStream.Dispose();
    264. }
    265. if (ent != null)
    266. {
    267. ent = null;
    268. }
    269. GC.Collect();
    270. GC.Collect(1);
    271. }
    272. return result;
    273. }
    274. ///
    275. /// 解压功能(解压压缩文件到指定目录)
    276. ///
    277. /// 待解压的文件
    278. /// 指定解压目标目录
    279. /// 解压结果
    280. public static bool UnZip(string fileToUnZip, string zipedFolder)
    281. {
    282. bool result = UnZip(fileToUnZip, zipedFolder, null);
    283. return result;
    284. }
    285. #endregion
    286. #region 使用GZIP解压
    287. public static bool UnZipFile(string zipFilePath)
    288. {
    289. if (!File.Exists(zipFilePath))
    290. {
    291. //Console.WriteLine("Cannot find file '{0}'", zipFilePath);
    292. return false;
    293. }
    294. try
    295. {
    296. using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
    297. {
    298. ZipEntry theEntry;
    299. while ((theEntry = s.GetNextEntry()) != null)
    300. {
    301. //Console.WriteLine(theEntry.Name);
    302. string directoryName =Path.GetDirectoryName(theEntry.Name);
    303. string fileName = Path.GetFileName(theEntry.Name);
    304. // create directory
    305. if (directoryName.Length > 0)
    306. {
    307. Directory.CreateDirectory(directoryName);
    308. }
    309. if (fileName != String.Empty)
    310. {
    311. using (FileStream streamWriter = File.Create(theEntry.Name))
    312. {
    313. int size = 2048;
    314. byte[] data = new byte[2048];
    315. while (true)
    316. {
    317. size = s.Read(data, 0, data.Length);
    318. if (size > 0)
    319. {
    320. streamWriter.Write(data, 0, size);
    321. }
    322. else
    323. {
    324. break;
    325. }
    326. }
    327. }
    328. }
    329. }
    330. }
    331. return true;
    332. }
    333. catch (Exception ex)
    334. {
    335. MessageBox.Show(ex.ToString());
    336. return false;
    337. }
    338. }
    339. ///
    340. /// 解压文件
    341. ///
    342. /// ZIP路径
    343. /// 解压到的路径
    344. ///
    345. public static string UnZipFile(string TargetFile, string fileDir)
    346. {
    347. string rootFile = " ";
    348. try
    349. {
    350. //读取压缩文件(zip文件),准备解压缩
    351. ZipInputStream s = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
    352. ZipEntry theEntry;
    353. string path = fileDir;
    354. //解压出来的文件保存的路径
    355. string rootDir = " ";
    356. //根目录下的第一个子文件夹的名称
    357. while ((theEntry = s.GetNextEntry()) != null)
    358. {
    359. rootDir = Path.GetDirectoryName(theEntry.Name);
    360. //得到根目录下的第一级子文件夹的名称
    361. if (rootDir.IndexOf("\\") >= 0)
    362. {
    363. rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
    364. }
    365. string dir = Path.GetDirectoryName(theEntry.Name);
    366. //根目录下的第一级子文件夹的下的文件夹的名称
    367. string fileName = Path.GetFileName(theEntry.Name);
    368. //根目录下的文件名称
    369. if (dir != " ")
    370. //创建根目录下的子文件夹,不限制级别
    371. {
    372. if (!Directory.Exists(fileDir + "\\" + dir))
    373. {
    374. path = fileDir + "\\" + dir;
    375. //在指定的路径创建文件夹
    376. Directory.CreateDirectory(path);
    377. //MessageBox.Show(path);
    378. }
    379. }
    380. else if (dir == " " && fileName != "")
    381. //根目录下的文件
    382. {
    383. path = fileDir;
    384. rootFile = fileName;
    385. }
    386. else if (dir != " " && fileName != "")
    387. //根目录下的第一级子文件夹下的文件
    388. {
    389. if (dir.IndexOf("\\") > 0)
    390. //指定文件保存的路径
    391. {
    392. path = fileDir + "\\" + dir;
    393. }
    394. }
    395. if (dir == rootDir)
    396. //判断是不是需要保存在根目录下的文件
    397. {
    398. path = fileDir + "\\" + rootDir;
    399. }
    400. //以下为解压缩zip文件的基本步骤
    401. //基本思路就是遍历压缩文件里的所有文件,创建一个相同的文件。
    402. if (fileName != String.Empty)
    403. {
    404. FileStream streamWriter = File.Create(path + "\\" + fileName);
    405. int size = 2048;
    406. byte[] data = new byte[2048];
    407. while (true)
    408. {
    409. size = s.Read(data, 0, data.Length);
    410. if (size > 0)
    411. {
    412. streamWriter.Write(data, 0, size);
    413. }
    414. else
    415. {
    416. break;
    417. }
    418. }
    419. streamWriter.Close();
    420. }
    421. }
    422. s.Close();
    423. return fileDir;
    424. }
    425. catch (Exception ex)
    426. {
    427. MessageBox.Show("解压失败,升级包路径为:"+ fileDir+"\r\n"+"异常为:"+ex.ToString());
    428. return "";
    429. }
    430. }
    431. #endregion
    432. }
    433. }

    启动两个下载参数:1. 下载文件位置 2. 下载文件版本号位置

    做了一个配置界面:

    主程序调用下载器:

    1. #region 检查更新
    2. private void 检查更新ToolStripMenuItem_Click(object sender, EventArgs e)
    3. {
    4. string checkVersion = "http://xxxx.com/NewVersion.txt";
    5. string newVersion = HttpHelper.GetHttpResponse(checkVersion, 5000,null);
    6. Console.WriteLine(newVersion);
    7. Version yun = new Version(newVersion);
    8. Version ben = new Version(this.ProductVersion);
    9. if (yun > ben)
    10. {
    11. String msg = string.Format("您当前版本:{0},最新版本为:{1},确定要升级到最新版本吗?", this.ProductVersion,newVersion);
    12. if (DialogResult.OK == MessageBox.Show(msg, "升级提示:升级过程中,将暂停服务!", MessageBoxButtons.OKCancel))
    13. {
    14. ExistDownUpdateSoft();
    15. Process.Start(this.applicationPath + "/AutoUpdate/AutoUpdate.exe");
    16. CloseAll();
    17. }
    18. }
    19. else {
    20. MessageBox.Show("已经是最新版!");
    21. }
    22. }
    23. ///
    24. /// 没有升级组件就下载,有就更新。直接返回
    25. ///
    26. ///
    27. private bool ExistDownUpdateSoft() {
    28. if (!File.Exists(this.applicationPath + "/AutoUpdate/AutoUpdate.exe"))
    29. {
    30. FrmForm.FrmUpdate frmUpdate = new FrmForm.FrmUpdate();
    31. DialogResult result = frmUpdate.ShowDialog();
    32. if (result == DialogResult.OK)
    33. {
    34. return true;
    35. }
    36. }
    37. return true;
    38. }
    39. private void CloseAll() {
    40. System.Environment.Exit(0);
    41. if (myThread != null)
    42. {
    43. myThread.Abort();
    44. }
    45. // 关闭所有的线程
    46. this.Dispose();
    47. this.Close();
    48. }
    49. #endregion

    如果将下载更新事件放到启动初始化中,就是成强制更新咯。

    至此winform自动升级程序完成!!!

    源代码会开源。需要的私信小编。。。。。。

     

  • 相关阅读:
    微软Copilot+ PC:Phi-Silica
    基本初等函数
    数列前n项和
    大模型应用开发:编写插件获取实时天气信息
    网络文化经营许可证
    vue的工程化开发全流程,以及开发中的细节语法和用法
    AUTOSAR知识点 之 多核启动 (一):英飞凌单片机的多核启动详细解析
    LeetCode 0263. 丑数
    CSS3------CSS大结局
    怎样考过PMP?零经验的我这样做
  • 原文地址:https://blog.csdn.net/u010919083/article/details/127915887