抽时间整理下升级这块的功能,并封装一个升级工具包。
作为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;
/// <summary>
/// 本地存储目录
/// </summary>
string ZipFilePath = Common.FilePathConfig.DownZIPPath;
/// <summary>
/// 本地解压目录
/// </summary>
string UnFilePath = Common.FilePathConfig.UnDownZIPPath;
/// <summary>
/// 开始升级程序客户端 author:huochengyan
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Start_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
Thread th = new Thread(StartUpdate);
th.IsBackground = true;
th.Start();
}
/// <summary>
/// 开始下载文件 升级
/// </summary>
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());
}
}
/// <summary>
/// 检查文件 解压
/// </summary>
/// <param name="UnZipFilePath"></param>
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();
}
/// <summary>
/// 启动最新下载的程序
/// </summary>
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;
}
/// <summary>
/// 时间 戳 事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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
{
/// <summary>
/// 适用与ZIP压缩
/// </summary>
public class ZIPHelper
{
#region 压缩
/// <summary>
/// 递归压缩文件夹的内部方法
/// </summary>
/// <param name="folderToZip">要压缩的文件夹路径</param>
/// <param name="zipStream">压缩输出流</param>
/// <param name="parentFolderName">此文件夹的上级文件夹</param>
/// <returns></returns>
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;
}
/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="folderToZip">要压缩的文件夹路径</param>
/// <param name="zipedFile">压缩文件完整路径</param>
/// <param name="password">密码</param>
/// <returns>是否压缩成功</returns>
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;
}
/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="folderToZip">要压缩的文件夹路径</param>
/// <param name="zipedFile">压缩文件完整路径</param>
/// <returns>是否压缩成功</returns>
public static bool ZipDirectory(string folderToZip, string zipedFile)
{
bool result = ZipDirectory(folderToZip, zipedFile, null);
return result;
}
/// <summary>
/// 压缩文件
/// </summary>
/// <param name="fileToZip">要压缩的文件全名</param>
/// <param name="zipedFile">压缩后的文件名</param>
/// <param name="password">密码</param>
/// <returns>压缩结果</returns>
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;
}
/// <summary>
/// 压缩文件
/// </summary>
/// <param name="fileToZip">要压缩的文件全名</param>
/// <param name="zipedFile">压缩后的文件名</param>
/// <returns>压缩结果</returns>
public static bool ZipFile(string fileToZip, string zipedFile)
{
bool result = ZipFile(fileToZip, zipedFile, null);
return result;
}
/// <summary>
/// 压缩文件或文件夹
/// </summary>
/// <param name="fileToZip">要压缩的路径</param>
/// <param name="zipedFile">压缩后的文件名</param>
/// <param name="password">密码</param>
/// <returns>压缩结果</returns>
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;
}
/// <summary>
/// 压缩文件或文件夹
/// </summary>
/// <param name="fileToZip">要压缩的路径</param>
/// <param name="zipedFile">压缩后的文件名</param>
/// <returns>压缩结果</returns>
public static bool Zip(string fileToZip, string zipedFile)
{
bool result = Zip(fileToZip, zipedFile, null);
return result;
}
#endregion
#region 解压
/// <summary>
/// 解压功能(解压压缩文件到指定目录)
/// </summary>
/// <param name="fileToUnZip">待解压的文件</param>
/// <param name="zipedFolder">指定解压目标目录</param>
/// <param name="password">密码</param>
/// <returns>解压结果</returns>
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;
}
/// <summary>
/// 解压功能(解压压缩文件到指定目录)
/// </summary>
/// <param name="fileToUnZip">待解压的文件</param>
/// <param name="zipedFolder">指定解压目标目录</param>
/// <returns>解压结果</returns>
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;
}
}
/// <summary>
/// 解压文件
/// </summary>
/// <param name="TargetFile">ZIP路径</param>
/// <param name="fileDir">解压到的路径</param>
/// <returns></returns>
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("已经是最新版!");
}
}
/// <summary>
/// 没有升级组件就下载,有就更新。直接返回
/// </summary>
/// <returns></returns>
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自动升级程序完成!!!
标签:fs,string,zipStream,升级,自动,result,using,null,Winform From: https://www.cnblogs.com/cdzh/p/17629312.html