首页 > 编程语言 >Winform 自动升级程序

Winform 自动升级程序

时间:2023-08-14 17:44:35浏览次数:57  
标签:fs string zipStream 升级 自动 result using null Winform

抽时间整理下升级这块的功能,并封装一个升级工具包。

作为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

相关文章

  • 利用K8S CronJob来实现etcd集群的自动备份
    前言:利用k8sCronJob来实现etcd集群的自动备份,并通过sftp传输到本k8s集群外的服务器上,进行存储。实验步骤:基本环境情况:服务器角色IP系统ETCD版本K8S集群操作服务器192.168.1.136Centos7.93.4.9存储服务器192.168.1.105Centos7.9-创建Dockerfile镜像:[root@k8s-master1~]#mkdir/s......
  • 新零售电商系统开发后如何进行维护和升级?
    一旦新零售电商系统完成开发并投入使用,维护和升级是确保系统持续高效运行的关键。随着技术的不断发展和用户需求的变化,定期进行维护和升级可以提升系统性能、修复漏洞,并满足用户不断增长的期望。下面,广州名锐讯动带大家一起来了解一下新零售电商系统开发后如何进行维护和升级。1.......
  • mysql 5.0升级到8.0
    1.替换新的驱动jar包       <dependency>           <groupId>com.mysql</groupId>           <artifactId>mysql-connector-j</artifactId>           <version>8.0.31</version>       </dependency>        ......
  • 直播间自动直播软件系统的优势
      直播间自动直播软件系统是一款无人直播帮助用户解答问题,让商家实现节省人力资源,解决用户的更多的问题,与传统的直播方式更加的省时省力,自动直播的软件有以下几种优势:  利用软件直播能提高的效率和质量。通过自动化的操作方式,软件能够快速地创建、管理和调整直播间,使得直......
  • 语音直播自动问答软件制作
      语音直播自动问答软件制作  人工智能技术已经深入到我们的生活中。在众多的人工智能应用中,语音直播自动问答软件制作是一种非常有趣的方式,它可以让用户在直播中与机器人互动并回答问题。本文将介绍语音直播自动问答软件制作的原理、流程和应用场景。  该软件系统的......
  • 优测云服务平台|【压力测试功能升级】轻松发压
    一、本次升级主要功能如下:1.多份报告对比查看测试结果2. 报告新增多种下载格式Word格式Excel格式3.新增多种编排复杂场景的控制器漏斗控制器并行控制器事务控制器仅一次控制器分组控制器集合点4. 新增概览页面,包含多种统计维度二、报告对比针对同一个压测场景,历史报告列表页......
  • 在安卓模拟器上如何实现HTTP代理自动切换
    在开发和测试应用程序时,有时需要在安卓模拟器上实现HTTP代理的自动切换以方便调试。本文将介绍如何在安卓模拟器上实现HTTP代理的自动切换。1.使用脚本文件使用脚本文件是一种实现HTTP代理自动切换的简单方法。以下是一个示例脚本文件:这个脚本定义了一个代理服务器地址和端口号数组......
  • Java 自动装箱与拆箱实战
    什么是自动装箱拆箱?很简单,下面两句代码就可以看到装箱和拆箱过程//自动装箱Integertotal=99;//自动拆箱inttotalprim=total;简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。下面我们来看看需要装箱拆箱的类型有哪些:这......
  • WinForm DevExpress 添加行内按钮
    1.在设计器里面添加一列,设置单元格不可编辑、只读属性   2.在所在GridView属性里面添加CustomDrawCell事件与RowCellClick事件privatevoidgvMain_CustomDrawCell(objectsender,DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgse){......
  • vscode终端git自动补全
    vscode终端git自动补全ctrl+shift+p输入setting.json,选择如下:加代码"terminal.integrated.profiles.windows":{"GitBash":{"path":"D:\\develop\\tool\\Git\\bin\\bash.exe",//注意是bash.exe而不是git-......