抽时间整理下升级这块的功能,并封装一个升级工具包。
作为winform 程序员都有一个C/S端程序绕不过的问题。那就是如何升级程序?
程序升级两种1.启动时强制更新 2.自动、手动获取更新,并确认是否升级。
今天咱们介绍,自动或者手动更新功能。
首先思考如何升级? 升级肯定要有一个新的升级文件包,还有一个本地版本和服务器版本号,因为这样才能对比是否升级。
看下下面的升级提示:
等待上面的升级下载程序完毕即可。会自动替换主程序,并启动主程序。
设计思路:我绘制了一张图可以从图中看。
1. 主程序开始升级,会检查是否有升级器有就启动下载,没有就去先下载升级器
2. 启动升级器,下载文件,下载后解压替换主程序。 并启动主程序。
下载器的一些代码:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Configuration;
- using System.Data;
- using System.Diagnostics;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
-
- namespace AutoUpdate
- {
- public partial class FrmMain : Form
- {
- public FrmMain()
- {
- InitializeComponent();
- }
-
- string Rootpath = Environment.CurrentDirectory;
-
- ///
- /// 本地存储目录
- ///
- string ZipFilePath = Common.FilePathConfig.DownZIPPath;
- ///
- /// 本地解压目录
- ///
- string UnFilePath = Common.FilePathConfig.UnDownZIPPath;
-
- ///
- /// 开始升级程序客户端 author:huochengyan
- ///
- ///
- ///
- private void button1_Start_Click(object sender, EventArgs e)
- {
- timer1.Enabled = true;
- Thread th = new Thread(StartUpdate);
- th.IsBackground = true;
- th.Start();
- }
- ///
- /// 开始下载文件 升级
- ///
- private void StartUpdate()
- {
- bool result = Common.HttpHelper.HttpDownload(Common.FilePathConfig.DownZIPUrl, ZipFilePath, this.progressBar1, this.label2_tishi);
- timer1.Enabled = false;
- if (result)
- {
- RefThisForm("下载成功!");
- Thread.Sleep(100);
- RefThisForm("正在解压,请稍后");
- if (!Directory.Exists(UnFilePath))
- Directory.CreateDirectory(UnFilePath);
- //UnFilePath = new FileInfo(ZipFilePath).DirectoryName;
-
-
- string reusult = Common.ZIPHelper.UnZipFile(ZipFilePath,UnFilePath);
- if (reusult != "")
- {
- RefThisForm("解压成功!");
- CheckUnZIPFile(reusult);
- }
- else
- {
- RefThisForm("解压失败!压缩包路径:" + ZipFilePath);
- }
- }
- else
- {
- MsgShow("下载失败!");
- }
-
-
- }
-
- private void FrmMain_Load(object sender, EventArgs e)
- {
- InitConfig();
- FrmMain.CheckForIllegalCrossThreadCalls = false;
-
- //删除陈旧的历史下载记录ZIP信息
- try
- {
- File.Delete(ZipFilePath);
- }
- catch (Exception ex)
- {
-
- }
- //检查下载器文件的dll
-
- button1_Start_Click(null, null);
-
- }
- private void CheckFile()
- {
- string UnZipdllPath = Rootpath + "/ICSharpCode.SharpZipLib.dll";
- if (!File.Exists(UnZipdllPath))
- {
- MessageBox.Show("下载器文件丢失:ICSharpCode.SharpZipLib.dll");
- }
- }
- private void InitConfig() {
- try
- {
- Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
- Common.FilePathConfig.DownZIPUrl = config.AppSettings.Settings["softURL"].Value;
-
- }
- catch (Exception ex)
- {
- MessageBox.Show("读取配置失败!" + ex.ToString());
- }
- }
- ///
- /// 检查文件 解压
- ///
- ///
- private void CheckUnZIPFile(string UnZipFileDirPath)
- {
- string mainexe = UnZipFileDirPath + "/LongDeTools.exe";
- Directory.SetCurrentDirectory(Directory.GetParent(UnZipFileDirPath).FullName);
- string OldFolder = Directory.GetCurrentDirectory();
- if (!File.Exists(mainexe))
- {
- MessageBox.Show("未能找到主程序:" + mainexe);
- return;
- }
- else {
- //覆盖源目录文件
- // string result=Common.FileHelper.CopyFolder(OldFolder,UnZipFileDirPath);
- //MessageBox.Show("请确认开始替换原始文件!");
- RefThisForm("安装中..."); //RefThisForm("替换原始主程序中。。。。");
-
- bool result1=Common.FileHelper.CopyOldLabFilesToNewLab(UnZipFileDirPath,OldFolder,0);
- if (result1)
- {
- RefThisForm("安装中..."); //RefThisForm("替换原始程序完毕。。。。");
- //清空解压的文件
- FileInfo fileinfo = new FileInfo(UnZipFileDirPath);
- try
- {
- if (Directory.Exists(fileinfo.FullName))
- {
- // MessageBox.Show("要删除的文件目录:" + fileinfo.FullName);
- Common.FileHelper.DelectDir(fileinfo.FullName);
- Common.FileHelper.DelectDir(Common.FilePathConfig.UnDownZIPPath);
- GC.Collect();
- }
- }
- catch (Exception ex)
- {
- MsgShow("清理下载文件垃圾失败!"+ex.ToString());
- }
- }
- else
- {
- MsgShow("升级失败!");
- }
- }
- //2. 启动新下载的程序
-
- StartNewSystem();
-
- GC.Collect();
-
- }
- ///
- /// 启动最新下载的程序
- ///
- private void StartNewSystem()
- {
- //string path = Environment.CurrentDirectory;
- //Directory.SetCurrentDirectory(Directory.GetParent(path).FullName);
- //path = Directory.GetCurrentDirectory();
- //string mainexe = path + "/LongDeTools.exe";
- string path=System.Windows.Forms.Application.StartupPath;
- string mainexe = "";
- if (Directory.Exists(path)) {
- mainexe = Directory.GetParent(path)+"/" + "LongDeTools.exe";
- }
- if (File.Exists(mainexe))
- {
- Process.Start(mainexe);
- RefThisForm("升级完成");
- MessageBox.Show("升级到最新版本!!!");
- this.Close();
-
- }
- else {
- MsgShow("要启动的文件不存在!!!"+mainexe);
- }
- ///清理下载的文件的缓存垃圾
- GC.Collect();
-
- }
- private void RefThisForm(string text)
- {
- this.Text = text;
- }
- ///
- /// 时间 戳 事件
- ///
- ///
- ///
- private void timer1_Tick(object sender, EventArgs e)
- {
- //Console.WriteLine("时间timer\r\n"+DateTime.Now.ToString()+"\r\n");
-
- label2_tishi.Text = progressBar1.Value/1048576+"M/"+ progressBar1.Maximum/ 1048576 + "M";
- if(progressBar1.Value== progressBar1.Maximum)
- label2_tishi.Text= progressBar1.Maximum / 1048576 + "M/" + progressBar1.Maximum / 1048576 + "M";
- }
-
- private void MsgShow(string msg) {
- MessageBox.Show(msg);
- }
-
- private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
- {
- FrmSetServer frm = new FrmSetServer();
- frm.ShowDialog();
- }
- }
- }
- using ICSharpCode.SharpZipLib.Checksums;
- using ICSharpCode.SharpZipLib.Zip;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
-
- namespace AutoUpdate.Common
- {
- ///
- /// 适用与ZIP压缩
- ///
- public class ZIPHelper
- {
- #region 压缩
-
- ///
- /// 递归压缩文件夹的内部方法
- ///
- /// 要压缩的文件夹路径
- /// 压缩输出流
- /// 此文件夹的上级文件夹
- ///
- private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
- {
- bool result = true;
- string[] folders, files;
- ZipEntry ent = null;
- FileStream fs = null;
- Crc32 crc = new Crc32();
-
- try
- {
- ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
- zipStream.PutNextEntry(ent);
- zipStream.Flush();
-
- files = Directory.GetFiles(folderToZip);
- foreach (string file in files)
- {
- fs = File.OpenRead(file);
-
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
- ent.DateTime = DateTime.Now;
- ent.Size = fs.Length;
-
- fs.Close();
-
- crc.Reset();
- crc.Update(buffer);
-
- ent.Crc = crc.Value;
- zipStream.PutNextEntry(ent);
- zipStream.Write(buffer, 0, buffer.Length);
- }
-
- }
- catch
- {
- result = false;
- }
- finally
- {
- if (fs != null)
- {
- fs.Close();
- fs.Dispose();
- }
- if (ent != null)
- {
- ent = null;
- }
- GC.Collect();
- GC.Collect(1);
- }
-
- folders = Directory.GetDirectories(folderToZip);
- foreach (string folder in folders)
- if (!ZipDirectory(folder, zipStream, folderToZip))
- return false;
-
- return result;
- }
-
- ///
- /// 压缩文件夹
- ///
- /// 要压缩的文件夹路径
- /// 压缩文件完整路径
- /// 密码
- ///
是否压缩成功 - public static bool ZipDirectory(string folderToZip, string zipedFile, string password)
- {
- bool result = false;
- if (!Directory.Exists(folderToZip))
- return result;
-
- ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
- zipStream.SetLevel(6);
- if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
-
- result = ZipDirectory(folderToZip, zipStream, "");
-
- zipStream.Finish();
- zipStream.Close();
-
- return result;
- }
-
- ///
- /// 压缩文件夹
- ///
- /// 要压缩的文件夹路径
- /// 压缩文件完整路径
- ///
是否压缩成功 - public static bool ZipDirectory(string folderToZip, string zipedFile)
- {
- bool result = ZipDirectory(folderToZip, zipedFile, null);
- return result;
- }
-
- ///
- /// 压缩文件
- ///
- /// 要压缩的文件全名
- /// 压缩后的文件名
- /// 密码
- ///
压缩结果 - public static bool ZipFile(string fileToZip, string zipedFile, string password)
- {
- bool result = true;
- ZipOutputStream zipStream = null;
- FileStream fs = null;
- ZipEntry ent = null;
-
- if (!File.Exists(fileToZip))
- return false;
-
- try
- {
- fs = File.OpenRead(fileToZip);
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- fs.Close();
-
- fs = File.Create(zipedFile);
- zipStream = new ZipOutputStream(fs);
- if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
- ent = new ZipEntry(Path.GetFileName(fileToZip));
- zipStream.PutNextEntry(ent);
- zipStream.SetLevel(6);
-
- zipStream.Write(buffer, 0, buffer.Length);
-
- }
- catch
- {
- result = false;
- }
- finally
- {
- if (zipStream != null)
- {
- zipStream.Finish();
- zipStream.Close();
- }
- if (ent != null)
- {
- ent = null;
- }
- if (fs != null)
- {
- fs.Close();
- fs.Dispose();
- }
- }
- GC.Collect();
- GC.Collect(1);
-
- return result;
- }
-
- ///
- /// 压缩文件
- ///
- /// 要压缩的文件全名
- /// 压缩后的文件名
- ///
压缩结果 - public static bool ZipFile(string fileToZip, string zipedFile)
- {
- bool result = ZipFile(fileToZip, zipedFile, null);
- return result;
- }
-
- ///
- /// 压缩文件或文件夹
- ///
- /// 要压缩的路径
- /// 压缩后的文件名
- /// 密码
- ///
压缩结果 - public static bool Zip(string fileToZip, string zipedFile, string password)
- {
- bool result = false;
- if (Directory.Exists(fileToZip))
- result = ZipDirectory(fileToZip, zipedFile, password);
- else if (File.Exists(fileToZip))
- result = ZipFile(fileToZip, zipedFile, password);
-
- return result;
- }
-
- ///
- /// 压缩文件或文件夹
- ///
- /// 要压缩的路径
- /// 压缩后的文件名
- ///
压缩结果 - public static bool Zip(string fileToZip, string zipedFile)
- {
- bool result = Zip(fileToZip, zipedFile, null);
- return result;
-
- }
-
- #endregion
-
- #region 解压
-
- ///
- /// 解压功能(解压压缩文件到指定目录)
- ///
- /// 待解压的文件
- /// 指定解压目标目录
- /// 密码
- ///
解压结果 - public static bool UnZip(string fileToUnZip, string zipedFolder, string password)
- {
- 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));
- 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('/', '\\');//change by Mr.HopeGi
-
- if (fileName.EndsWith("\\"))
- {
- Directory.CreateDirectory(fileName);
- continue;
- }
-
- fs = File.Create(fileName);
- int size = 2048;
- byte[] data = new byte[size];
- while (true)
- {
- size = zipStream.Read(data, 0, data.Length);
- if (size > 0)
- fs.Write(data, 0, data.Length);
- else
- break;
- }
- }
- }
- }
- catch
- {
- 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;
- }
-
- ///
- /// 解压功能(解压压缩文件到指定目录)
- ///
- /// 待解压的文件
- /// 指定解压目标目录
- ///
解压结果 - public static bool UnZip(string fileToUnZip, string zipedFolder)
- {
- bool result = UnZip(fileToUnZip, zipedFolder, null);
- return result;
- }
-
- #endregion
-
- #region 使用GZIP解压
- public static bool UnZipFile(string zipFilePath)
- {
- if (!File.Exists(zipFilePath))
- {
- //Console.WriteLine("Cannot find file '{0}'", zipFilePath);
- return false;
- }
- try
- {
- using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
- {
-
- ZipEntry theEntry;
- while ((theEntry = s.GetNextEntry()) != null)
- {
-
- //Console.WriteLine(theEntry.Name);
-
- string directoryName =Path.GetDirectoryName(theEntry.Name);
- string fileName = Path.GetFileName(theEntry.Name);
-
- // create directory
- if (directoryName.Length > 0)
- {
- Directory.CreateDirectory(directoryName);
- }
-
- if (fileName != String.Empty)
- {
- using (FileStream streamWriter = File.Create(theEntry.Name))
- {
-
- int size = 2048;
- byte[] data = new byte[2048];
- while (true)
- {
- size = s.Read(data, 0, data.Length);
- if (size > 0)
- {
- streamWriter.Write(data, 0, size);
- }
- else
- {
- break;
- }
- }
- }
- }
- }
- }
- return true;
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString());
- return false;
- }
- }
-
- ///
- /// 解压文件
- ///
- /// ZIP路径
- /// 解压到的路径
- ///
- public static string UnZipFile(string TargetFile, string fileDir)
- {
- string rootFile = " ";
- try
- {
- //读取压缩文件(zip文件),准备解压缩
- ZipInputStream s = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
- ZipEntry theEntry;
- string path = fileDir;
- //解压出来的文件保存的路径
-
- string rootDir = " ";
- //根目录下的第一个子文件夹的名称
- while ((theEntry = s.GetNextEntry()) != null)
- {
- rootDir = Path.GetDirectoryName(theEntry.Name);
- //得到根目录下的第一级子文件夹的名称
- if (rootDir.IndexOf("\\") >= 0)
- {
- rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
- }
- string dir = Path.GetDirectoryName(theEntry.Name);
- //根目录下的第一级子文件夹的下的文件夹的名称
- string fileName = Path.GetFileName(theEntry.Name);
- //根目录下的文件名称
- if (dir != " ")
- //创建根目录下的子文件夹,不限制级别
- {
- if (!Directory.Exists(fileDir + "\\" + dir))
- {
- path = fileDir + "\\" + dir;
- //在指定的路径创建文件夹
- Directory.CreateDirectory(path);
- //MessageBox.Show(path);
- }
- }
- else if (dir == " " && fileName != "")
- //根目录下的文件
- {
- path = fileDir;
- rootFile = fileName;
- }
- else if (dir != " " && fileName != "")
- //根目录下的第一级子文件夹下的文件
- {
- if (dir.IndexOf("\\") > 0)
- //指定文件保存的路径
- {
- path = fileDir + "\\" + dir;
- }
- }
-
- if (dir == rootDir)
- //判断是不是需要保存在根目录下的文件
- {
- path = fileDir + "\\" + rootDir;
- }
-
- //以下为解压缩zip文件的基本步骤
- //基本思路就是遍历压缩文件里的所有文件,创建一个相同的文件。
- if (fileName != String.Empty)
- {
- FileStream streamWriter = File.Create(path + "\\" + fileName);
-
- int size = 2048;
- byte[] data = new byte[2048];
- while (true)
- {
- size = s.Read(data, 0, data.Length);
- if (size > 0)
- {
- streamWriter.Write(data, 0, size);
- }
- else
- {
- break;
- }
- }
-
- streamWriter.Close();
- }
- }
- s.Close();
-
- return fileDir;
- }
- catch (Exception ex)
- {
- MessageBox.Show("解压失败,升级包路径为:"+ fileDir+"\r\n"+"异常为:"+ex.ToString());
- return "";
- }
- }
-
- #endregion
- }
-
- }
启动两个下载参数:1. 下载文件位置 2. 下载文件版本号位置
做了一个配置界面:
主程序调用下载器:
- #region 检查更新
-
- private void 检查更新ToolStripMenuItem_Click(object sender, EventArgs e)
- {
- string checkVersion = "http://xxxx.com/NewVersion.txt";
- string newVersion = HttpHelper.GetHttpResponse(checkVersion, 5000,null);
- Console.WriteLine(newVersion);
- Version yun = new Version(newVersion);
- Version ben = new Version(this.ProductVersion);
- if (yun > ben)
- {
- String msg = string.Format("您当前版本:{0},最新版本为:{1},确定要升级到最新版本吗?", this.ProductVersion,newVersion);
- if (DialogResult.OK == MessageBox.Show(msg, "升级提示:升级过程中,将暂停服务!", MessageBoxButtons.OKCancel))
- {
- ExistDownUpdateSoft();
- Process.Start(this.applicationPath + "/AutoUpdate/AutoUpdate.exe");
- CloseAll();
- }
- }
- else {
- MessageBox.Show("已经是最新版!");
- }
- }
-
- ///
- /// 没有升级组件就下载,有就更新。直接返回
- ///
- ///
- private bool ExistDownUpdateSoft() {
- if (!File.Exists(this.applicationPath + "/AutoUpdate/AutoUpdate.exe"))
- {
- FrmForm.FrmUpdate frmUpdate = new FrmForm.FrmUpdate();
- DialogResult result = frmUpdate.ShowDialog();
- if (result == DialogResult.OK)
- {
- return true;
- }
- }
- return true;
- }
-
- private void CloseAll() {
- System.Environment.Exit(0);
- if (myThread != null)
- {
- myThread.Abort();
- }
- // 关闭所有的线程
- this.Dispose();
- this.Close();
- }
-
- #endregion
如果将下载更新事件放到启动初始化中,就是成强制更新咯。
至此winform自动升级程序完成!!!
源代码会开源。需要的私信小编。。。。。。