winform软件版本检测自动升级开发流程

基于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的帖子,通过他的代码我整理和优化的代码,以上为简单的代码复制,因为今天比较忙,来不及细致整理,等忙完这两天我会细化一下,我直接上附件,大家看源码一看就明白,

源码下载地址:源码下载地址

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
一、软件开发环境以及开发工具: 框架:.NET Framework 4.0 工具:Visual Studio 2017 插件:DevExpress 18.1.7 环境:IIS 7 二、实现步骤 (1)在项目中创建一个名为WinformAutoUpdate.APP的Winform窗体应用工程,并将默认的Form1.cs窗体文件重命名为MainFrm.cs作为主程序窗体 创建主程序窗体 (2)在项目中再创建一个名为AutoUpdateTask的Winform应用程序工程,并将默认的Form1.cs窗体文件重命名为AutoUpdateTaskFrm.cs作为更新程序窗体 创建更新程序窗体 (3)在更新程序窗体中放入图上所示的相关控件; 进度条控件用于显示更新进度,放入一个Button按钮控件用于用户根据提示进行操作! 实现思路: 1、将更新程序放入磁盘的目录下面,并将其放在已经发布了的IIS中 当用户在运行主程序窗体并点击左上角的更新按钮时,弹出程序更新窗体,并先自动从IIS中拉取updateList.xml文件,然后与本地程序作对比,检测是否需要升级软件; 如果有新版本发布,则点击“立即更新”按钮,程序将从IIS中拉取新发布的ZIP软件包,并自动解压到主程序目录中,覆盖主程序目录中的相关文件(这里值得注意的是,在解压程序之前,我们需要先结束主程序的进程,不然会因主程序进程正在使用而导致报错,另外,我们用到的插件是ICSharpCode.SharpZipLib.dll第三方动态链接库,网上有现成的,可以直接Down下来用);
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值