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();
}

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

4962

被折叠的 条评论
为什么被折叠?



