C#实现程序的版本在线升级更新
文章目录
- 背景
- 代码
- 下载地址
- 设置到的知识点
- 参考文献
背景
最近在做开发的时候,需要程序有自动版本升级的功能。特此记录下整个过程。
代码
注意事项:
- 服务器端需要上传XML配置文件和待下载的软件
- 本地AssemblyInfo需要填写版本,和服务器端XML文件的版本号进行比较
直接上代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.NET;
using System.Xml; namespace Update
{ /// <summary> /// 更新完成触发的事件 /// </summary> public delegate void UpdateState(); /// <summary> /// 程序更新 /// </summary> public class SoftUpdate { private string download; private const string updateUrl = "http://www.csdn.Net/update.xml";//升级配置的XML文件地址 #region 构造函数 public SoftUpdate() { } /// <summary> /// 程序更新 /// </summary> /// <param name="file">要更新的文件</param> public SoftUpdate(string file,string softName) { this.LoadFile = file; this.SoftName = softName; } #endregion #region 属性 private string loadFile; private string newVerson; private string softName; private bool isUpdate; /// <summary> /// 或取是否需要更新 /// </summary> public bool IsUpdate { get { checkUpdate(); return isUpdate; } } /// <summary> /// 要检查更新的文件 /// </summary> public string LoadFile { get { return loadFile; } set { loadFile = value; } } /// <summary> /// 程序集新版本 /// </summary> public string NewVerson { get { return newVerson; } } /// <summary> /// 升级的名称 /// </summary> public string SoftName { get { return softName; } set { softName = value; } } #endregion /// <summary> /// 更新完成时触发的事件 /// </summary> public event UpdateState UpdateFinish; private void isFinish() { if(UpdateFinish != null) UpdateFinish(); } /// <summary> /// 下载更新 /// </summary> public void Update() { try { if (!isUpdate) return; WebClient wc = new WebClient(); string filename = ""; string exten = download.Substring(download.LastIndexOf(".")); if (loadFile.IndexOf(@"/") == -1) filename = "Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten; else filename = Path.GetDirectoryName(loadFile) + "//Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten; wc.DownloadFile(download, filename); wc.Dispose(); isFinish(); } catch { throw new Exception("更新出现错误,网络连接失败!"); } } /// <summary> /// 检查是否需要更新 /// </summary> public void checkUpdate() { try { WebClient wc = new WebClient(); Stream stream = wc.OpenRead(updateUrl); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(stream); XmlNode list = xmlDoc.SelectSingleNode("Update"); foreach(XmlNode node in list) { if(node.Name == "Soft" && node.Attributes["Name"].Value.ToLower() == SoftName.ToLower()) { foreach(XmlNode xml in node) { if(xml.Name == "Verson") newVerson = xml.InnerText; else download = xml.InnerText; } } } Version ver = new Version(newVerson); Version verson = Assembly.LoadFrom(loadFile).GetName().Version; int tm = verson.CompareTo(ver); if(tm >= 0) isUpdate = false; else isUpdate = true; } catch(Exception ex) { throw new Exception("更新出现错误,请确认网络连接无误后重试!"); } } /// <summary> /// 获取要更新的文件 /// </summary> /// <returns></returns> public override string ToString() { return this.loadFile; } }
}
下面是更新的XML文件类容,传到服务器上就可以了,得到XML文件的地址。
<?xml version="1.0" encoding="utf-8" ?>
<Update> <Soft Name="BlogWriter"> <Verson>1.0.1.2</Verson> <DownLoad>http://www.csdn.net/BlogWrite.rar</DownLoad> </Soft>
</Update>
程序更新调用方法如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;
using System.Xml;
using Update;namespace UpdateTest
{public partial class Form1 : Form{public Form1(){InitializeComponent();checkUpdate();}public void checkUpdate(){SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "BlogWriter");app.UpdateFinish += new UpdateState(app_UpdateFinish);try{if (app.IsUpdate && MessageBox.Show("检查到新版本,是否更新?", "Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes){Thread update = new Thread(new ThreadStart(app.Update));update.Start();}}catch (Exception ex){MessageBox.Show(ex.Message);}}void app_UpdateFinish(){MessageBox.Show("更新完成,请重新启动程序!", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information);}}
}
如果需要异步下载并且显示下载进度信息,可以按照如下函数进行修改
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Wolfy.DownLoad
{public partial class MainFrm : Form{private string _saveDir;public MainFrm(){InitializeComponent();_saveDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "download");}private void MainFrm_Load(object sender, EventArgs e){if (!Directory.Exists(_saveDir)){Directory.CreateDirectory(_saveDir);}}private void btnDownLoad_Click(object sender, EventArgs e){string imageUrl = "http://image.3761.com/nvxing/2016022921/2016022921382152113.jpg";string fileExt = Path.GetExtension(imageUrl);string fileNewName = Guid.NewGuid() + fileExt;bool isDownLoad = false;string filePath = Path.Combine(_saveDir, fileNewName);if (File.Exists(filePath)){isDownLoad = true;}var file = new FileMessage{FileName = fileNewName,RelativeUrl = "nvxing/2016022921/2016022921382152113.jpg",Url = imageUrl,IsDownLoad = isDownLoad,SavePath = filePath};if (!file.IsDownLoad){string fileDirPath = Path.GetDirectoryName(file.SavePath);if (!Directory.Exists(fileDirPath)){Directory.CreateDirectory(fileDirPath);}try{WebClient client = new WebClient();client.DownloadFileCompleted += client_DownloadFileCompleted;client.DownloadProgressChanged += client_DownloadProgressChanged;client.DownloadFileAsync(new Uri(file.Url), file.SavePath, file.FileName);}catch{}}}void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e){if (e.UserState != null){this.lblMessage.Text = e.UserState.ToString() + ",下载完成";}}void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){this.proBarDownLoad.Minimum = 0;this.proBarDownLoad.Maximum = (int)e.TotalBytesToReceive;this.proBarDownLoad.Value = (int)e.BytesReceived;this.lblPercent.Text = e.ProgressPercentage + "%";}}
}
在这过程中还参考了别人的代码过程,以及B站课程
下载地址:https://gakkiwife.lanzoub.com/ix8rN06eqtde
下载地址
c#的整体代码可以通过链接进行下载:
https://gakkiwife.lanzoub.com/iEc8u06eyfni
设置到的知识点
- 更新触发事件代码
public delegate void UpdateState();
/// <summary>
/// 更新完成时触发的事件
/// </summary>
public event UpdateState UpdateFinish;
#调用触发事件
app.UpdateFinish += new UpdateState(app_UpdateFinish);
void app_UpdateFinish(){MessageBox.Show("下载完成,请点击进行安装!", "Update", MessageBoxButtons.OK,MessageBoxIcon.Information);}
- set、get默认设置
public SoftUpdate(string file, string softName)
{this.LoadFile = file;this.SoftName = softName;
}
/// <summary>
/// 要检查更新的文件
/// </summary>
public string LoadFile
{get { return loadFile; }set { loadFile = value; }
}
/// <summary>
/// 升级的名称
/// </summary>
public string SoftName
{get { return softName; }set { softName = value; }
}
参考文献
- https://www.cnblogs.com/shadowme/p/6250089.html
- https://www.cnblogs.com/wolf-sun/p/6699733.html
C#实现程序的版本在线升级更新相关推荐
- 软件包管理 之 软件在线升级更新yum 图形工具介绍
作者:北南南北 来自:LinuxSir.Org 提要:yum 是Fedora/Redhat 软件包管理工具,包括文本命令行模式和图形模式:图形模式的yum也是基于文本模式的:目前yum图形前端程序主要 ...
- electron在线升级更新的两种方式(整体更新和部分更新)及我是如何实现electron在线升级热更新功能的?(企业级项目已上线)
这篇主要以讲解部分资源在线热更新的实现为核心,electron自带的整体更新的实现较简单,简单说一下即可,如有疑问点的可以自行查阅相关资料或在下面留言给我即可 一.electron的在线升级更新方式都 ...
- HBuilder实现App资源在线升级更新
本文只要介绍HBuilder实现App资源在线升级更新. 梳理思路: 1.获取线上App版本号和当前App版本号 2.比对版本号,判断是否资源在线升级更新 3.是否下载最新安装包[可以静默下载或用户触 ...
- SequoiaDB版本在线升级介绍说明
1. 前言 在SequoiaDB数据库发展过程中,基本保持每半年对外发行一个正式的Release版本.并且每个新发布的Release版本相对老版本而言,性能方面都有很大的提高,并且数据库也会在新版本中 ...
- C#单exe程序在线升级更新
有一个小工具,除了配置文件就只有一个exe主程序,以前弄别的工具有引用一些dll,还做了更新器,这个小工具不想弄太复杂,希望保持单exe又具有在线升级的功能,网上看到有人问过同样问题,写下我的方法以作 ...
- mfc 更新服务器文件,MFC程序版本自动升级更新
1.自动升级需要实现两个exe程序的交替启动,需要一个主程序和一个升级程序:在一个解决方案中创建两个项目,一个是你的主程序,另一个为你的升级程序:第二个程序创建选择添加到解决方案,同时选中你要添加的位 ...
- Java程序如何自动在线升级
有时候我们的程序需要连接服务器检测新版本,如果发现新版本则需要自动下载升级.这种需求在Linux下还好说,但在windows下如何替换正在运行的程序文件呢? 当然有办法,步骤如下: 1. 将我们的程序 ...
- 解决macOS无法在线升级更新的问题
macOS在线更新功能本来十分方便,但是本人macbook pro自从10.14.x开始(包括Catalina 10.15.x)就无法直接更新.开始时提示.下载.运行更新程序.自动重启安装... 一切 ...
- 用C#实现C/S模式下软件自动在线升级[转载]
摘要: 本文针对目前C/S模式下编写的应用程序可维护性差的特点,提出了一套自动在线升级的解决方案,分析了在线升级的困难及实现原理,并给出了实现升级的部分代码,具有实际参考价值和现实意义.本文程序代码均 ...
最新文章
- pl/sql中三种游标循环效率对比
- 自建mysql和华为云mysql_自建数据库和云数据库区别和使用(以MySQL为例)
- 797C C. Minimal string
- Qt for ios 打开图片和 office文件
- 离散数学关系的性质_关系和关系的性质| 离散数学
- django.db.utils.OperationalError: (1040, ‘Too many connections‘)
- birt报表模板只打印了第一行_财务系统全套表格模板201个!成为同事眼中的红人!低调分享...
- 【NLP】XLNet详解
- 扫锚工具:xscan.exe
- Matlab RRT算法三维轨迹规划及贪心算法轨迹优化
- 【全网最强C语言学习】C语言入门(工具)——库函数字典MSDN
- Docker基础教程
- hget和get redis_Redis Hash 的 HSET、HGET、HMSET、HMGET 性能测试
- 用js实现建议绘图板
- Chrome网页下载提速小技巧
- Ecshop各个页面文件介绍,主要文件功能说明
- OpenEmbedded 简介
- 【信息系统项目管理师】第三章 立项管理思维导图
- VS2017 专业版 离线安装实践 Visual Studio 2017
- 北洋(HOKUYO)雷达在ROS Kinetic下使用
热门文章
- 嵌入式邻域面试官必问的问题
- 智能家居(6) —— 香橙派摄像头安装实现监控功能
- 我的世界手机版服务器显示即将推出,我的世界手机版1.12即将发布 第一个预览版已经曝光...
- AbstractUser
- linux终端打开画图,如何在Ubuntu 18.04中安装协同绘画软件Drawpile
- 品《人生》之感,思“人生”之路
- 方法论分享之:刻意练习,微小改进
- Excel转Pdf —— jacob
- 十五. 单线激光雷达和视觉信息融合
- CSS中的font-family字体集,附在chrome浏览器中的效果图