Winform在线升级

本文介绍了一个Winform应用在线升级的具体实现过程,包括版本比较、升级包下载与解压、文件替换及重启等关键步骤,并提供了服务端和客户端的代码示例。

winform在线升级要点

  • 比较版本
  • 下载并解压升级包
  • 还原用户配置(可选)
  • 升级包文件替换原程序文件
  • 重启

服务端开发

提供对外的服务,以最简单的获取版本和获取升级包为例子

        /// <summary>
        /// GetVersion
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string GetVersion()
        {
            return "1.1.0.0";
        }
        
        /// <summary>
        /// GetUpdateFiles
        /// </summary>
        /// <param name="password">password</param>
        /// <returns></returns>
        [HttpGet]
        public string GetUpdateFiles()
        {
            return "UpdateFiles/PDCA/update.zip";
        }

客户端开发

1、开发界面

在这里插入图片描述

2、比较版本

       private void btnCheck_BtnClick(object sender, EventArgs e)
        {
            var versionResult = ClientManageApiService.GetVersion();//获取远程服务器版本
            
            //比较新老版本
            if (!CompareVersion(versionResult.Result, ConfigStrs.SystemVersion))
            {
                MessageBox.Show("当前已是最新版本", "提示");
                return;
            }
        }
        
        /// <summary>
        /// 版本号比较:new_version>=old_version
        /// </summary>
        /// <param name="new_version">8.4.0</param>
        /// <param name="old_version">8.3.10</param>
        /// <returns></returns>
        public static bool CompareVersion(string new_version, string old_version)
        {
            try
            {
                if (string.IsNullOrEmpty(new_version) || string.IsNullOrEmpty(old_version))
                    return false;

                Version v_new = new Version(new_version);
                Version v_old = new Version(old_version);
                if (v_new > v_old)
                    return true;
                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

3、下载并解压升级包

    /// <summary>
    /// 更新
    /// </summary>
    private void Update()
    {
        string str = Application.StartupPath + @"\NewVersions";
        if (!Directory.Exists(str)) Directory.CreateDirectory(str);

        string url = str + @"\update.zip";//本地存放路径
        string DownUrl =  #######;//远程下载路径
        bool flag = DownloadFile(DownUrl, url, this.prgUpdateLoad);
        if (flag)
        {
            // 解压到 NewVersions
            if (SystemService.UnZip(url, str, ConfigStrs.ZipPassword) == false)
            {
                MessageBox.Show("升级包解压失败.");
                return;
            }
            // 删除 NewVersions 下的压缩包
            File.Delete(url);
            
            //更新数据库脚本 TODO
            
            // 启动 bat 脚本
            Cmd("reboot.bat", Application.StartupPath);
            
            // 退出当前应用程序
            Process.GetCurrentProcess().Kill();//此方法完全奏效,绝对是完全退出。
        }
    }

    /// <summary>
    /// 下载ZIP压缩包到指定的目录下
    /// </summary>
    /// <param name="URL">下载的链接</param>
    /// <param name="filename">压缩包文件名,包含路径</param>
    /// <param name="prog">进度条</param>
    /// <returns></returns>
    private bool DownloadFile(string URL, string filename, UCProcessLine prog)
    {
        float percent = 0;
        try
        {
            HttpWebRequest Myrq = (HttpWebRequest)HttpWebRequest.Create(URL);
            HttpWebResponse myrp = (HttpWebResponse)Myrq.GetResponse();
            long totalBytes = myrp.ContentLength;
            if (prog != null)
            {
                //prog.Maximum = (int)totalBytes;
                prog.MaxValue = (int)totalBytes;
            }
            Stream st = myrp.GetResponseStream();
            Stream so = new FileStream(filename, FileMode.Create);
            long totalDownloadedByte = 0;
            byte[] by = new byte[1024 * 50];
            int osize = st.Read(by, 0, (int)by.Length);
            while (osize > 0)
            {
                totalDownloadedByte = osize + totalDownloadedByte;
                so.Write(by, 0, osize);
                if (prog != null)
                {
                    prog.Value = (int)totalDownloadedByte;
                }
                osize = st.Read(by, 0, (int)by.Length);

                percent = (float)totalDownloadedByte / (float)totalBytes * 100;
                var lblText = $"下载{percent.ToInt32(0)}%";
                if (lblText != lblLoadMsg.Text)
                {
                    lblLoadMsg.Text = lblText;
                    Application.DoEvents(); //必须加注这句代码,否则label1将因为循环执行太快而来不及显示信息
                }
            }
            so.Close();
            st.Close();
            return true;
        }
        catch (Exception)
        {
            return false;
            throw;
        }
    }

    // 解压ZIP压缩包到指定的目录下
    public static bool UnZip(string fileToUnZip, string zipedFolder, string password = null)
    {
        bool result = true;
        FileStream fs = null;
        ZipInputStream zipStream = null;
        ZipEntry ent = null;
        string fileName;

        if (!File.Exists(fileToUnZip)) return false;
        if (!Directory.Exists(zipedFolder)) Directory.CreateDirectory(zipedFolder);

        try
        {
            zipStream = new ZipInputStream(File.OpenRead(fileToUnZip.Trim()));
            if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
            while ((ent = zipStream.GetNextEntry()) != null)
            {
                if (!string.IsNullOrEmpty(ent.Name))
                {
                    fileName = Path.Combine(zipedFolder, ent.Name);
                    fileName = fileName.Replace('/', '\\');
                    if (fileName.EndsWith("\\"))
                    {
                        Directory.CreateDirectory(fileName);
                        continue;
                    }
                    using (fs = File.Create(fileName))
                    {
                        int size = 1024 * 50;
                        byte[] data = new byte[size];
                        while (true)
                        {
                            size = zipStream.Read(data, 0, data.Length);
                            if (size > 0) fs.Write(data, 0, size);
                            else break;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            LogHelper.AddError(ex, string.Empty, "UnZip");
            result = false;
        }
        finally
        {
            if (fs != null)
            {
                fs.Close();
                fs.Dispose();
            }
            if (zipStream != null)
            {
                zipStream.Close();
                zipStream.Dispose();
            }
            if (ent != null)
            {
                ent = null;
            }
            GC.Collect();
            GC.Collect(1);
        }
        return result;
    }

4、升级包文件替换原程序文件且重启

新增文件reboot.bat
在这里插入图片描述

TIMEOUT /T 3
del *.exe
del *.dll
robocopy "NewVersions/Release" "." /move /e
start JBToolsWinPro.exe
       /// <summary>
        /// 调用系统cmd命令,执行bat命令
        /// </summary>
        /// <param name="bat"></param>
        /// <param name="workingDirectory"></param>
        public static void Cmd(string bat, string workingDirectory)
        {
            var proc = new Process();
            proc.StartInfo.FileName = bat;
            proc.StartInfo.WorkingDirectory = workingDirectory;
            proc.StartInfo.UseShellExecute = true;
            proc.StartInfo.RedirectStandardInput = false;
            proc.StartInfo.RedirectStandardOutput = false;
            proc.StartInfo.RedirectStandardError = false;
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            proc.StartInfo.CreateNoWindow = false;
            proc.Start();
            proc.Close();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值