window平台C#实现软件更新功能

 一 实现程序更新思路

    程序实现自我升级,一般有两种方式:

1. 独立的更新程序

开发一个独立的更新程序如Update.exe,用于检查主程序是否有新版本,并下载和安装新版本。

实现步骤:

  1. 主程序启动完后,调用一下更新程序。
  2. 更新程序检查版本不需要更新就退出否则执行更新。
  3. 更新程序检查主程序的版本号。
  4. 如果主程序的版本号低于服务器上的版本号,则下载新版本。
  5. 下载完成后,更新程序将新版本安装到主程序的目录中(一般要备份旧版的)。
  6. 更新程序重启主程序。

优点:

  • 更新过程对用户透明,用户无需手动操作。
  • 可以实现增量更新,只下载更新的文件,节省流量。

缺点:

  • 更新程序需要访问服务器,如果服务器不可访问,则无法更新。

2. 主程序自带更新功能

 将更新功能集成到主程序中,无需开发额外的更新程序。

实现步骤如下:

  1. 主程序启动时,向服务器发送请求,检查是否有新版本。
  2. 如果有新版本,则服务器返回新版本的版本号和下载地址。
  3. 主程序下载新版本。
  4. 下载完成后,主程序将新版本安装到自己的目录中。
  5. 主程序重启自身。

优点:

  • 开发简单,在更新过程中无需考虑与主程序通讯。

缺点:

  • 每次更新都需要下载整个程序,比较耗流量,在更新后不能很好实现自我重启,需要用脚本或者其它方式。

二  程序更新代码(独立的更新程序

 1 主程序增加调用更新程序代码:

  public void CheckForUpdates(){// 检查是否存在更新程序if (File.Exists("Update.exe")){// 启动更新程序try{Process.Start("Update.exe");}catch (Exception e){}}}

2 update.exe完整代码:

        //这部分用于隐藏窗体或控制台,一般静默更新,重启才提示。[DllImport("kernel32.dll")]static extern IntPtr GetConsoleWindow();[DllImport("user32.dll")]static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);const int SW_HIDE = 0;String processName = "xxx平台";String mainFilePath = "xxx平台.exe";String infaceVersion = "";String updateUrl = "http://192.168.22.100:1888/pc/getVersionInfo";String downloadUrlExe = "http://192.168.22.144:8904/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe";String downloadFileName = "test.exe";public Form1(){InitializeComponent();// 获取控制台窗口句柄IntPtr hWnd = GetConsoleWindow();// 隐藏控制台窗口ShowWindow(hWnd, SW_HIDE);}private void Form1_Load(object sender, EventArgs e){Update();}//更新程序public void Update(){// 获取主程序的版本号String version = GetVersion(mainFilePath);// 检查是否有新版本String newVersion = GetVersionFromWeb();if (newVersion != null){// 如果有新版本,则下载新版本if (CompareVersion(newVersion, version) == 1){Log("本地版本:"+version);Log("符合更新条件,开始更新…");Log("开始下载…");if (DownloadNewVersion()){// 安装新版本Log("开始更新程序…");InstallNewVersion();Log("启动主程序…");// 重启主程序Process.Start(mainFilePath);Log("启动主程序ok");}else{Log("因下载环节问题终止更新操作!");}}else{Log("没有的新条件,退出");}}else{Log("获取服务器版本失败!");}Log("更新程序退出.");Environment.Exit(0);}/// <summary>/// 下载新版本并验证版本号/// </summary>/// <returns></returns>private Boolean DownloadNewVersion(){WebClient wcClient = new WebClient();// 下载文件并保存到指定位置WebClient client = new WebClient();Log("获取下载url: "+ downloadUrlExe);byte[] data = client.DownloadData(downloadUrlExe);Log("下载文件大小[" + data.Length/1024 + " kb]");String tempPath = "./" + downloadFileName;// 将字节数组保存到文件File.WriteAllBytes(tempPath, data);Log("保存位置 " + tempPath);//验证版本 是否与接口一致String version = GetVersion(tempPath);bool vaildVersion = version.Equals(infaceVersion);Log("验证已下载文件版本("+version+")与 接口版本("+infaceVersion+"): " + vaildVersion);return vaildVersion;}/// <summary>/// 安装/// </summary>private void InstallNewVersion(){Log("开始关闭主程序…");Process[] ppp= Process.GetProcessesByName(processName);if (ppp.Length > 0){MessageBox.Show("正在执行升级,重启远程鉴定平台。");try{for (int i = 0; i < ppp.Length; i++){Log("结束进程:" + ppp[i].ProcessName);ppp[i].Kill();}}catch(Exception ex){Log("结束进程:" +ex.Message);}}Log("备份主程序…");if (!Directory.Exists("./bak")){Directory.CreateDirectory("./bak");}DateTime currentDateAndTime = DateTime.Now;String time= currentDateAndTime.ToString("yyyyMMddHHmmss");String bakPath = "./bak/" + mainFilePath + "." + time;File.Copy(mainFilePath,bakPath,true);Log("备份主程序完成。");int waitTimeMilliseconds = 1000; // 5秒Thread.Sleep(waitTimeMilliseconds);File.Delete(mainFilePath);Log("删除旧版程序OK。 ");File.Copy(downloadFileName,mainFilePath);Log("更新文件OK。 ");File.Delete(downloadFileName);Log("删除下载文件OK。 ");}private String GetVersionFromWeb(){Log("准备获取服务器版本号…");String json =request(updateUrl);//{"msg":"操作成功","code":200,"data":{"id":589,"versionCode":3,"versionName":"1.0.0.1","updateContent":"test","fileName":"xxx平台.exe","saveName":"2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe","fileSuffix":".exe","fileSize":"107KB","url":"http://192.168.22.144:8904/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe","type":2,"uploadTime":"2024-03-26 10:17:29"}}JsonElement element = JsonDocument.Parse(json).RootElement;infaceVersion = element.GetProperty("data").GetProperty("versionName").GetString();Log("获取服务器版本号:" + infaceVersion);downloadUrlExe = element.GetProperty("data").GetProperty("url").GetString();Log("获取服务器下载URL:" + downloadUrlExe);downloadFileName = element.GetProperty("data").GetProperty("saveName").GetString();Log("获取服务器下载文件名称:" + downloadFileName);return infaceVersion;}/// <summary>/// 日记记录/// </summary>/// <param name="v"></param>private void Log(string v){//DateTime currentDateAndTime = DateTime.Now;//richTextBox1.AppendText(currentDateAndTime.ToString() +" - "+ v+"\n");String filePath = "./update.log";try{using (StreamWriter writer = new StreamWriter(filePath, true)){string logEntry = $"{DateTime.Now} - {v}";writer.WriteLine(logEntry);}}catch (Exception ex){// 记录异常信息Console.WriteLine("日志记录失败:" + ex.Message);}}/// <summary>/// http请求/// </summary>/// <param name="url"></param>/// <returns></returns>public static string request(string url){using (WebClient client = new WebClient()){return client.DownloadString(url);}}/// <summary>/// 获取文件版本号/// </summary>/// <param name="path"></param>/// <returns></returns>private String GetVersion(string path){richTextBox1.AppendText("准备获取本地版本号……:" + path+"\n");// 获取文件版本信息FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(path);// 获取文件版本号string fileVersion = fileVersionInfo.FileVersion;richTextBox1.AppendText("获取本地版本号:" + fileVersion + "\n");return fileVersion;}/// <summary>/// 比较软件的版本号/// </summary>/// <param name="version1"></param>/// <param name="version2"></param>/// <returns></returns>public static int CompareVersion(string version1, string version2){string[] parts1 = version1.Split('.');string[] parts2 = version2.Split('.');for (int i = 0; i < parts1.Length && i < parts2.Length; i++){int v1 = int.Parse(parts1[i]);int v2 = int.Parse(parts2[i]);if (v1 > v2){return 1;}else if (v1 < v2){return -1;}}return 0;}

执行后的更新日记 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/568760.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

30岁失业的我,选择职场转型,进入AIGC工程师领域,重新开始

去年&#xff0c;刚满30岁的我又一次被公司辞退了&#xff0c;由于学历不高&#xff0c;简历也不出彩&#xff0c;尽管半个月来投了一份又一份的简历&#xff0c;但仍然是石沉大海&#xff0c;我终于不得不开始思考一个以前被我一直刻意压制的想法——职场转型。 尽管知道这条…

笔记—学习【立创】如何使用示波器—捕捉波形

如何使用示波器的信号触发功能 在工程实践中&#xff0c;经常要测量一些不连续的波形。例如&#xff0c;USART、SPI、IIC通讯&#xff0c;只有在通讯时才会产生相应的波形&#xff0c;如果示波器的触发模式没有选择好的话&#xff0c;我们是看不到这个波形的。 切换触发模式 …

ChatGPT 提示词:2024最新AIGC提示词大全(文末名片获取电子书)

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

DARTS-: ROBUSTLY STEPPING OUT OF PERFORMANCE COLLAPSE WITHOUT INDICATORS

DARTS-&#xff1a;增加辅助跳跃连接&#xff0c;鲁棒走出搜索性能崩溃 论文链接&#xff1a;https://arxiv.org/abs/2009.01027 项目链接&#xff1a;GitHub - Meituan-AutoML/DARTS-: Code for “DARTS-: Robustly Stepping out of Performance Collapse Without Indicators…

linux 系统安装php 8.0.2

1. 安装包准备 https://www.php.net/distributions/php-8.0.22.tar.gz 我下载到 /usr/local/src 这个目录了 cd /usr/local/srcwget https://www.php.net/distributions/php-8.0.22.tar.gz 2. tar 解压 然后进到解压的文件夹 tar -zxvf php-8.0.22.tar.gz cd php-8.0.2…

C语言 汉诺塔问题

目录 1.前言 2.问题描述 3.问题分析 4.定义一个主函数 5.再定义一个hanoi函数 6.所有代码 7.结语 1.前言 汉诺塔问题&#xff0c;是心理学实验研究常用的任务之一。该问题的主要材料包括三根高度相同的柱子和一些大小及颜色不同的圆盘&#xff0c;三根柱子分别为起始柱A…

制作小程序需要多少钱?成本分析与效益预测

在当今数字化时代&#xff0c;微信小程序已成为企业和个人拓展业务的重要工具。然而&#xff0c;许多人在考虑进入这一领域时&#xff0c;都会面临一个关键问题&#xff1a;制作一个小程序需要多少钱&#xff1f;下面和你一起探讨小程序开发的成本因素&#xff0c;帮助你更好地…

HCIP的学习(4)

GRE和MGRE VPN---虚拟专用网络。指依靠ISP&#xff08;运营商&#xff09;或其他公有网络基础设施上构建的专用的安全数据通信网络。该网络是属于逻辑上的。​ 核心机制—隧道机制&#xff08;封装技术&#xff09; GRE—通用路由封装 ​ 三层隧道技术&#xff0c;并且是属于…

WebPack的使用及属性配、打包资源

WebPack(静态模块打包工具)(webpack默认只识别js和json内容) WebPack的作用 把静态模块内容压缩、整合、转译等&#xff08;前端工程化&#xff09; 1️⃣把less/sass转成css代码 2️⃣把ES6降级成ES5 3️⃣支持多种模块文件类型&#xff0c;多种模块标准语法 export、export…

获客助手怎么实现抖音巨量广告回传?

在数字化营销的世界里&#xff0c;数据就像是宝藏&#xff0c;不断被挖掘、分析并应用。而抖音巨量广告回传&#xff0c;就是那把开启宝藏之门的钥匙。通过专门的工具将目标数据进行反馈&#xff0c;巨量系统接收数据后进行优化&#xff0c;广告模型构建速度加快&#xff0c;推…

AXI_Lite协议详解

文章目录 摘要一、AXI_Lite接口全局信号&#xff1a;1、写地址通道&#xff1a;2、写数据通道&#xff1a;3、写响应通道&#xff1a;4、读地址通道&#xff1a;5、读数据通道&#xff1a; 二、仿真波形 摘要 AXI4-lite是AXI4-full的简化版。用于简单、低吞吐量的内存映射通信…

Java异常知识点详解

目录 1. 异常的概念与体系结构 1.1 异常的概念 1. 算术异常 2. 数组越界异常 3. 空指针异常 1.2 异常的体系结构 1.3 异常的分类 2. 异常的处理 2.1 防御式编程 2.2 异常的抛出 2.3 异常声明throws 2.4 try-catch捕获并处理 2.5 finally 2.4 异常的处理流程 3. 自…