注:按此博文试验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软件版本检测自动升级开发流程(转)的更多相关文章

  1. C/S软件的自动升级部署

    升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级.当然也有人用其它属性比较的,例如:文件大小,或者更新日期.而实现的方法呢? 在.Net时代,我们就有了更多的选择 ...

  2. 在WinForm中使用Web Service来实现软件自动升级

    来源:互联网 winform程序相对web程序而言,功能更强大编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术 ...

  3. 在WinForm中使用Web Services 来实现 软件自动升级( Auto Update ) (C#)

    winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了 ...

  4. 在WinForm中使用Web Services 来实现 软件 自动升级( Auto Update ) (C#)

    winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,面对这个实际问题,在最近的一个小项目中,本人设计了一个通过软件实现自动升级技术方案,弥补了 ...

  5. 在C#中实现软件自动升级

    在C#中实现软件自动升级 winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,本文结合实际情况,通过软件实现自动升级,弥补了这一缺陷,有较好的 ...

  6. java CS结构软件自动升级的实现

    前段时间做了一个工具发布给公司的各部门使用后反馈了不少BUG,每次修改后均需要发邮件通知各用户替换最新版本,很不方便,因此后来就写了一个自动升级的功能,这样每次发布新的版本时只需要将其部署到自动升级服 ...

  7. SNF开发平台WinForm之八-自动升级程序部署使用说明-SNF快速开发平台3.3-Spring.Net.Framework

    9.1运行效果: 9.2开发实现: 1.首先配置服务器端,把“SNFAutoUpdate2.0\服务器端部署“目录按网站程序进行发布到IIS服务器上. 2.粘贴语句,生成程序 需要调用的应用程序的Lo ...

  8. 分享一个客户端程序(winform)自动升级程序,思路+说明+源码

    做winform的程序,不管用没用过自动更新,至少都想过自动更新是怎么实现的. 我这里共享一个自动更新的一套版本,给还没下手开始写的人一些帮助,也希望有大神来到,给指点优化意见. 本初我是通过sock ...

  9. HTML5进阶(二)HBuilder实现软件自动升级

    HBuilder实现软件自动升级 前言 移动APP开发好后需要实现软件自动升级功能,经过一番搜索,发现HBuilder具有"App资源在线升级更新"的功能,遂研究之. 经过一番测试 ...

随机推荐

  1. maya 在 pymel 中运行 mel

    maya 在 pymel 中运行 mel 前言 maya mel 自身定义了很多有用的方法,当我们用 pymel 开发的时候,不想重新写一遍 mel 已经有的功能,那么就可以在 pymel 中运行 m ...

  2. python学习之正则表达式,StringIO模块,异常处理,搭建测试环境

    python正则表达式 引入一个强大的匹配功能来匹配字符串 import re 正则表达式的表示类型raw string类型(原生字符串类型) r'sa\\/sad/asd'用r转为raw strin ...

  3. m_strcpy

    自己实现strcpy函数 #include <stdio.h> #include <assert.h> //如果它的条件返回错误,则终止程序执行 char *m_strcpy( ...

  4. canvas圆形进度条(逆时针)

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  5. Robot Framework--Scalar变量

    一.变量赋值 1)Set赋值 通常使用Set Variable关键字对变量进行赋值,其他Set相关的带Variable的关键字也可以进行赋值 赋值的时候,变量后面写不写『=』都可以,如下: 如果${v ...

  6. webpack中配置babel时遇到的问题

    1.Error: Cannot find module '@babel/core' babel-loader@8 requires Babel 7.x (the package '@babel/cor ...

  7. 云计算(8)--MapReduce如何处理fault

    一些常见的故障 NM周期性的给RM发送heartbeats,如果RM发现server fails,则它会让所有与这个server有关的AM知道,让受影响的job的AM采取一些action,重新分配它的 ...

  8. GitHub常用命令及使用

    GitHub使用介绍 摘要: 常用命令: git init 新建一个空的仓库git status 查看状态git add . 添加文件git commit -m '注释' 提交添加的文件并备注说明gi ...

  9. unsafe包的学习和使用

    Go语言之unsafe包介绍及使用 unsafe内容介绍 type ArbitraryType int type Pointer *ArbitraryType func Sizeof(x Arbitr ...

  10. django 渲染模板与 vue 的 {{ }} 冲突解决方法

    如果不可避免的在同一个页面里既有 django 渲染又有 vue 渲染的部分,可有 2 种方式解决 方法一: 采用 vue 的 delimiters  分隔符. new Vue({ delimiter ...