winform软件版本检测自动升级开发流程(转)
注:按此博文试验OK
基于C/S的开发有开发效率高,对于业务逻辑复杂,且不需要外网使用具有较大优势,但是弊端也不可忽视,就是升级麻烦,不可能每写一个版本就要拿着安装包给每个人去替换,这样不仅搞得自己很累,对于使用者来说也会厌烦,所以对于版本自动升级就显得必不可少,好,废话到此为止,下面直接上硬货
1、升级界面
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using Update;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace autoUpdate
{
public partial class Form1 : Form
{
[DllImport("zipfile.dll")]
public static extern int MyZip_ExtractFileAll(string zipfile, string pathname);
public Form1()
{
InitializeComponent();
//清除之前下载来的rar文件
if (File.Exists(Application.StartupPath + "\\Update_autoUpdate.zip"))
{
try
{
File.Delete(Application.StartupPath + "\\Update_autoUpdate.zip");
}
catch (Exception)
{
}
}
if (Directory.Exists(Application.StartupPath + "\\autoupload"))
{
try
{
Directory.Delete(Application.StartupPath + "\\autoupload", true);
}
catch (Exception)
{
}
}
//检查服务端是否有新版本程序
checkUpdate();
timer1.Enabled = true;
}
SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "ExceTransforCsv");
public void checkUpdate()
{
app.UpdateFinish += new UpdateState(app_UpdateFinish);
try
{
if (app.IsUpdate)
{
app.Update();
}
else
{
MessageBox.Show("未检测到新版本!");
Application.Exit();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void app_UpdateFinish()
{
//解压下载后的文件
string path = app.FinalZipName;
if (File.Exists(path))
{
//后改的 先解压滤波zip植入ini然后再重新压缩
string dirEcgPath = Application.StartupPath + "\\" + "autoupload";
if (!Directory.Exists(dirEcgPath))
{
Directory.CreateDirectory(dirEcgPath);
}
//开始解压压缩包
MyZip_ExtractFileAll(path, dirEcgPath);
try
{
//复制新文件替换旧文件
DirectoryInfo TheFolder = new DirectoryInfo(dirEcgPath);
foreach (FileInfo NextFile in TheFolder.GetFiles())
{
File.Copy(NextFile.FullName, Application.StartupPath + "\\program\\" + NextFile.Name, true);
}
Directory.Delete(dirEcgPath, true);
File.Delete(path);
//覆盖完成 重新启动程序
path = Application.StartupPath + "\\program";
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "ExceTransforCsv.exe";
process.StartInfo.WorkingDirectory = path;//要掉用得exe路径例如:"C:\windows";
process.StartInfo.CreateNoWindow = true;
process.Start();
Application.Exit();
}
catch (Exception)
{
MessageBox.Show("请关闭系统在执行更新操作!");
Application.Exit();
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = "下载文件进度:" + COMMON.CommonMethod.autostep.ToString() + "%";
this.progressBar1.Value = COMMON.CommonMethod.autostep;
if (COMMON.CommonMethod.autostep == 100)
{
timer1.Enabled = false;
}
}
}
}
有一点需要注意:zipfile.dll或者myzip.dll只能解压zip格式的压缩包 ,不要被带入误区,这个困扰我很久
2、版本检测升级类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Reflection;
using COMMON;
using System.Threading;
namespace Update
{
/// <summary>
/// 更新完成触发的事件
/// </summary>
public delegate void UpdateState();
/// <summary>
/// 程序更新
/// </summary>
public class SoftUpdate
{
private string download;
private const string updateUrl = "http://192.168.11.4:8055/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; }
}
private string _finalZipName = string.Empty;
public string FinalZipName
{
get { return _finalZipName; }
set { _finalZipName = 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;
FinalZipName = filename;
//wc.DownloadFile(download, filename);
wc.DownloadFileAsync(new Uri(download), filename);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
//wc.Dispose();
}
catch
{
throw new Exception("更新出现错误,网络连接失败!");
}
}
void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
(sender as WebClient).Dispose();
isFinish();
}
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
//System.Diagnostics.Debug.WriteLine(e.ProgressPercentage);
COMMON.CommonMethod.autostep = e.ProgressPercentage;
//Thread.Sleep(100);
}
/// <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;
}
}
}
3、主要复制进度条的value值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace COMMON
{
public static class CommonMethod
{
public static int autostep;
}
}
4、程序入口处检测版本是否更新
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Update;
namespace PrintDemo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
if (checkUpdateLoad())
{
Application.Exit();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public static bool checkUpdateLoad()
{
bool result = false;
SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "ExceTransforCsv");
try
{
if (app.IsUpdate && MessageBox.Show("检查到新版本,是否更新?", "版本检查", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
string path = Application.StartupPath.Replace("program", "");
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "autoUpdate.exe";
process.StartInfo.WorkingDirectory = path;//要掉用得exe路径例如:"C:\windows";
process.StartInfo.CreateNoWindow = true;
process.Start();
result = true;
}
else
{
result = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
result = false;
}
return result;
}
}
}
5、服务器上需要一个版本控制的xml,格式如下
<?xml version="1.0" encoding="utf-8" ?>
<Update>
<Soft Name="ExceTransforCsv">
<Verson>1.0.0.3</Verson>
<DownLoad>http://192.168.11.4:8055/Update_autoUpdate.zip</DownLoad>
</Soft>
</Update>
6、软件版本使用.net自带的版本控制即可,如下
7、重点强调,因为主程序升级需要将主程序关闭,所以需要将升级程序放到外边,将主程序放到program中,
运行界面:
首先感谢变成论坛上用户:wangnannan的帖子,通过他的代码我整理和优化的代码,以上为简单的代码复制,因为今天比较忙,来不及细致整理,等忙完这两天我会细化一下,我直接上附件,大家看源码一看就明白,
---------------------
原文:https://blog.csdn.net/xiaodong728/article/details/81083239
winform软件版本检测自动升级开发流程(转)的更多相关文章
- C/S软件的自动升级部署
升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级.当然也有人用其它属性比较的,例如:文件大小,或者更新日期.而实现的方法呢? 在.Net时代,我们就有了更多的选择 ...
- 在WinForm中使用Web Service来实现软件自动升级
来源:互联网 winform程序相对web程序而言,功能更强大编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术 ...
- 在WinForm中使用Web Services 来实现 软件自动升级( Auto Update ) (C#)
winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了 ...
- 在WinForm中使用Web Services 来实现 软件 自动升级( Auto Update ) (C#)
winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了 ...
- 在C#中实现软件自动升级
在C#中实现软件自动升级 winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,本文结合实际情况,通过软件实现自动升级,弥补了这一缺陷,有较好的 ...
- java CS结构软件自动升级的实现
前段时间做了一个工具发布给公司的各部门使用后反馈了不少BUG,每次修改后均需要发邮件通知各用户替换最新版本,很不方便,因此后来就写了一个自动升级的功能,这样每次发布新的版本时只需要将其部署到自动升级服 ...
- SNF开发平台WinForm之八-自动升级程序部署使用说明-SNF快速开发平台3.3-Spring.Net.Framework
9.1运行效果: 9.2开发实现: 1.首先配置服务器端,把“SNFAutoUpdate2.0\服务器端部署“目录按网站程序进行发布到IIS服务器上. 2.粘贴语句,生成程序 需要调用的应用程序的Lo ...
- 分享一个客户端程序(winform)自动升级程序,思路+说明+源码
做winform的程序,不管用没用过自动更新,至少都想过自动更新是怎么实现的. 我这里共享一个自动更新的一套版本,给还没下手开始写的人一些帮助,也希望有大神来到,给指点优化意见. 本初我是通过sock ...
- HTML5进阶(二)HBuilder实现软件自动升级
HBuilder实现软件自动升级 前言 移动APP开发好后需要实现软件自动升级功能,经过一番搜索,发现HBuilder具有"App资源在线升级更新"的功能,遂研究之. 经过一番测试 ...
随机推荐
- c++ vector容器基本用法
基本用法 #include<iostream> #include<string> #include<vector> using namespace std; cla ...
- Ubuntu增加swap交换空间的步骤
1.首先用命令free查看系统内 Swap 分区大小. free -m total used free shared buffers cached Mem: 2012 1960 51 0 748 95 ...
- 【MySQL】explicit_defaults_for_timestamp 参数详解
简介:explicit_defaults_for_timestamp 系统变量决定MySQL服务端对timestamp列中的默认值和NULL值的不同处理方法. 此变量自MySQL 5.6.6 版本引入 ...
- SpringMVC数据格式化
SpringMVC数据格式化 1. 使用Formatter格式化数据 Converter可以将一种类型转换成另一种类型,是任意Object之间的类型转换. Formatter则只能进行String与任 ...
- Nginx 做JavaWeb负载均衡
随着用户量的增大,单台服务器已经满足不了用户的需求. 准备工作:安装 gcc.pcre-devel.zlib.OpenSSL 一下是在线 离线请戳这里 gcc 安装安装 nginx 需要先将官网下 ...
- 树状数组例题-数星星,简单题easy,校门外的树2,清点人数
[例1]数星星 天空中有一些星星,这些星星都在不同的位置,每个星星都有个坐标,如果一个星星的左下方(包括正左和正下)有k颗星星,就说这颗星星是k级的. 比如,上图中,星星5是3级的(1,2,4在其左下 ...
- php面向对象之$this->用法简述
在成员方法中,调用成员方法的方法是对象名加方法名,格式就是“对象名->方法名”.但是在定义类的时候,我们往往不知道对象名是什么,所以就没法用对象名,这时,我们就要用到伪变量$this. 什么是$ ...
- 07_Kibana界面操作ES
Kibana界面的API操作ES 1.创建索引 1.1 指定分片数量和备份数量 1.2 创建默认 2. 查看索引 2.1 查看单个索引设置 2.2 查看所有索引设置 3.文档管理 3.1 添加文档 3 ...
- spring boot 扫描 其他jar包里面的 mapper xml
启动类配置扫描 goods.mapper为当前项目mapper路径 ,common.mpper为其他jar包. 1. 2.mybatis.mapper-locations=classpath*:map ...
- Airflow 配置celery+rabbitmq和celery+redis
Airflow 配置celery+rabbitmq 1.安装celery和rabbitmq组件 pip3 install apache-airflow[celery] pip3 install apa ...