• window平台C#实现软件升级功能(控制台)


     window平台C#实现软件升级功能

           之前用window窗体实现过一个升级功能,后来发现多个项目都需要升级功能,现改成可接收参数实现一种通用的exe.改用控制台方式实现这个升级功能,这样不仅实现了接收参数,升级程序体积也比原来的窗体形式更小。

    一  Window窗体升级实现:

    window平台C#实现软件升级功能(Window窗体应用)_开发电脑软件自动更新怎么实现-CSDN博客

     

    二  控制台升级实现:

      1 关于升级细路,这里不再详细写,可参考上面Window窗体升级实现。

      2 完整C#控制台升级程序代码如下:

    1. using System;
    2. using System.Diagnostics;
    3. using System.IO;
    4. using System.IO.Compression;
    5. using System.Net;
    6. using System.Runtime.InteropServices;
    7. using System.Text.Json;
    8. using System.Threading;
    9. namespace ConsoleAppUpdate
    10. {
    11. class Program
    12. {
    13. static String processName = "xxx应用";
    14. static String mainFilePath = "xxx应用.exe";
    15. static String infaceVersion = "";
    16. static String updateUrl = "https://xxx.xxx.xxx.xxx/pc/getLastApp";
    17. static String downloadUrlExe = "http://xxx.xxx.xxx.xx:89/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe";
    18. static String downloadFileName = "test.exe";
    19. // 导入 Windows API 函数
    20. [DllImport("user32.dll", CharSet = CharSet.Auto)]
    21. public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
    22. // 用visual studio 编译时 要配置
    23. static void Main(string[] args)
    24. {
    25. // 参数1 升级接口 url
    26. // 参数2 进程名称 用于关闭进程
    27. // 参数3 主文件名称 (不用指定目录,要求把升级文件放在主文件同一目录即可)
    28. if (args != null && args.Length > 1)
    29. {
    30. updateUrl = args[0];
    31. Log("rev update url = " + updateUrl);
    32. }
    33. else
    34. {
    35. Log("use default update url = " + updateUrl);
    36. }
    37. try
    38. {
    39. Update();
    40. }
    41. catch (Exception ee)
    42. {
    43. Log("update program Exception :" + ee.Message);
    44. }
    45. finally
    46. {
    47. Environment.Exit(0);
    48. }
    49. }
    50. //更新程序
    51. public static void Update()
    52. {
    53. Log("开始检测更新……");
    54. // 获取主程序的版本号
    55. String version = GetVersion(mainFilePath);
    56. // 检查是否有新版本
    57. String newVersion = GetVersionFromWeb();
    58. if (newVersion != null)
    59. {
    60. if ("0.0.0.0".Equals(version))
    61. {
    62. Log("原主程序,直接更新.");
    63. Log("开始下载…");
    64. if (DownloadNewVersion())
    65. {
    66. // 安装新版本
    67. Log("开始更新程序…");
    68. InstallNewVersion();
    69. Log("启动主程序…");
    70. // 重启主程序
    71. Process.Start(mainFilePath);
    72. Log("启动主程序ok");
    73. }
    74. else
    75. {
    76. Log("因下载环节问题终止更新操作!");
    77. }
    78. }
    79. else
    80. {
    81. // 如果有新版本,则下载新版本
    82. if (CompareVersion(newVersion, version) == 1)
    83. {
    84. Log("本地版本:" + version);
    85. Log("符合更新条件,开始更新…");
    86. Log("开始下载…");
    87. if (DownloadNewVersion())
    88. {
    89. // 安装新版本
    90. Log("开始更新程序…");
    91. InstallNewVersion();
    92. Log("启动主程序…");
    93. // 重启主程序
    94. Process.Start(mainFilePath);
    95. Log("启动主程序ok");
    96. }
    97. else
    98. {
    99. Log("因下载环节问题终止更新操作!");
    100. }
    101. }
    102. else
    103. {
    104. Log("没有的新条件,退出");
    105. }
    106. }
    107. }
    108. else
    109. {
    110. Log("获取服务器版本失败!");
    111. }
    112. Log("更新程序退出.");
    113. Environment.Exit(0);
    114. }
    115. ///
    116. /// 下载新版本并验证版本号
    117. ///
    118. ///
    119. private static Boolean DownloadNewVersion()
    120. {
    121. WebClient wcClient = new WebClient();
    122. // 下载文件并保存到指定位置
    123. WebClient client = new WebClient();
    124. Log("获取下载url: " + downloadUrlExe);
    125. byte[] data = client.DownloadData(downloadUrlExe);
    126. Log("下载文件大小[" + data.Length / 1024 + " kb]");
    127. String tempPath = "./" + downloadFileName;
    128. // 将字节数组保存到文件
    129. File.WriteAllBytes(tempPath, data);
    130. Log("保存位置 " + tempPath);
    131. //验证版本 是否与接口一致
    132. String version = GetVersion(tempPath);
    133. bool vaildVersion = version.Equals(infaceVersion);
    134. Log("验证已下载文件版本(" + version + ")与 接口版本(" + infaceVersion + "): " + vaildVersion);
    135. return vaildVersion;
    136. }
    137. ///
    138. /// 安装
    139. ///
    140. private static void InstallNewVersion()
    141. {
    142. Log("开始关闭主程序…");
    143. Process[] ppp = Process.GetProcessesByName(processName);
    144. if (ppp.Length > 0)
    145. {
    146. MessageBox(IntPtr.Zero, "正在执行升级,重启远程鉴定平台。", "升级提示", 0);
    147. try
    148. {
    149. for (int i = 0; i < ppp.Length; i++)
    150. {
    151. Log("结束进程:" + ppp[i].ProcessName);
    152. ppp[i].Kill();
    153. }
    154. }
    155. catch (Exception ex)
    156. {
    157. Log("结束进程异常:" + ex.Message);
    158. }
    159. }
    160. Log("备份主程序…");
    161. if (!Directory.Exists("./bak"))
    162. {
    163. Directory.CreateDirectory("./bak");
    164. }
    165. DateTime currentDateAndTime = DateTime.Now;
    166. String time = currentDateAndTime.ToString("yyyyMMddHHmmss");
    167. String bakPath = "./bak/" + mainFilePath + "." + time;
    168. if (File.Exists(mainFilePath))
    169. {
    170. File.Copy(mainFilePath, bakPath, true);
    171. Log("备份主程序完成。");
    172. int waitTimeMilliseconds = 1000; // 5秒
    173. Thread.Sleep(waitTimeMilliseconds);
    174. File.Delete(mainFilePath);
    175. Log("删除旧版程序OK。 ");
    176. }
    177. if (downloadFileName.EndsWith(".zip",StringComparison.CurrentCultureIgnoreCase))
    178. {
    179. //如果升级包是zip 先解压
    180. try
    181. {
    182. // 解压zip文件到当前目录
    183. ZipFile.ExtractToDirectory(downloadFileName, "./");
    184. Console.WriteLine("Zip文件解压成功!");
    185. File.Delete(downloadFileName);
    186. Log("删除下载文件OK。 ");
    187. }
    188. catch (Exception ex)
    189. {
    190. Console.WriteLine("解压zip文件时出错:" + ex.Message);
    191. }
    192. }
    193. else
    194. {
    195. File.Copy(downloadFileName, mainFilePath);
    196. Log("更新主程序完成。");
    197. File.Delete(downloadFileName);
    198. Log("删除下载文件OK。 ");
    199. }
    200. }
    201. private static String GetVersionFromWeb()
    202. {
    203. Log("准备获取服务器版本号…");
    204. String json = request( updateUrl);
    205. //{"msg":"操作成功","code":200,"data":{"versionName":"1.0.0.1","updateContent":"test","fileSize":"107KB","url":"http://192.168.22.144:8904/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe","uploadTime":"2024-03-26 10:17:29"}}
    206. JsonElement element = JsonDocument.Parse(json).RootElement;
    207. infaceVersion = element.GetProperty("data").GetProperty("versionName").GetString();
    208. Log("获取服务器版本号:" + infaceVersion);
    209. downloadUrlExe = element.GetProperty("data").GetProperty("url").GetString();
    210. Log("获取服务器下载URL:" + downloadUrlExe);
    211. downloadFileName = element.GetProperty("data").GetProperty("saveName").GetString();
    212. Log("获取服务器下载文件名称:" + downloadFileName);
    213. return infaceVersion;
    214. }
    215. ///
    216. /// 日记记录
    217. ///
    218. ///
    219. private static void Log(string v)
    220. {
    221. String filePath = "./update.log";
    222. try
    223. {
    224. using (StreamWriter writer = new StreamWriter(filePath, true))
    225. {
    226. string logEntry = $"{DateTime.Now} - {v}";
    227. writer.WriteLine(logEntry);
    228. }
    229. }
    230. catch (Exception ex)
    231. {
    232. // 记录异常信息
    233. Console.WriteLine("日志记录失败:" + ex.Message);
    234. }
    235. }
    236. ///
    237. /// http请求
    238. ///
    239. ///
    240. ///
    241. public static string request(string url)
    242. {
    243. using (WebClient client = new WebClient())
    244. {
    245. return client.DownloadString(url);
    246. }
    247. }
    248. ///
    249. /// 获取文件版本号
    250. ///
    251. ///
    252. ///
    253. private static String GetVersion(string path)
    254. {
    255. Log("获取本地版本号……:" + path + "\n");
    256. if (!File.Exists(path))
    257. {
    258. string currentDirectory = Directory.GetCurrentDirectory();
    259. Console.WriteLine("Current Directory: " + currentDirectory);
    260. path = currentDirectory + "\\" + path;
    261. if (!File.Exists(path))
    262. {
    263. Log("检测不到主文件,直接返回原始版本号");
    264. return "0.0.0.0";
    265. }
    266. }
    267. // 获取文件版本信息
    268. FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(path);
    269. // 获取文件版本号
    270. string fileVersion = fileVersionInfo.FileVersion;
    271. Log("获取本地版本号:" + fileVersion + "\n");
    272. return fileVersion;
    273. }
    274. ///
    275. /// 比较软件的版本号
    276. ///
    277. ///
    278. ///
    279. ///
    280. public static int CompareVersion(string version1, string version2)
    281. {
    282. string[] parts1 = version1.Split('.');
    283. string[] parts2 = version2.Split('.');
    284. for (int i = 0; i < parts1.Length && i < parts2.Length; i++)
    285. {
    286. int v1 = int.Parse(parts1[i]);
    287. int v2 = int.Parse(parts2[i]);
    288. if (v1 > v2)
    289. {
    290. return 1;
    291. }
    292. else if (v1 < v2)
    293. {
    294. return -1;
    295. }
    296. }
    297. return 0;
    298. }
    299. }
    300. }

         因为升级是后台进行的,所以编译代码时 不要显示控制台,改一下:

    1. 打开 Visual Studio 中的项目。
    2. 在解决方案资源管理器中,右键单击项目,然后选择“属性”。
    3. 在属性窗口中,选择“应用程序”选项卡。
    4. 在“输出类型”下拉菜单中选择“Windows 应用程序”。
    5. 保存更改并重新构建项目。

    如下图:

    代码编译后,发现引用了很多dll,原因是因为升级接口返回的是json数据所以使用了一个json解析用到几个dll,需要复制到需要用到升级功能的项目即可。

    实现效果图如下:

     

    查看更新日记 

     

    测试完美实现更新。 

  • 相关阅读:
    webpack5学习进阶:模块、依赖与扩展功能(PostCSS、Web Works、TypeScript)
    Day08 模板
    玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
    基于瞬时无功功率ip-iq的谐波信号检测Simulink仿真
    JS中的函数
    山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计
    jar包导入到本地仓库无法引用
    理科生的人生感悟-02-别忘了别人的痛苦 - 丰收之歌和围墙外的稻田
    【手把手带你学JavaSE系列】String类(上篇)
    Redis集群
  • 原文地址:https://blog.csdn.net/qyhua/article/details/138184268