QT 实现软件在线更新功能
更新程序只需要替换部分需要更新的文件,不必整个程序重新安装。
主程序在运行的时候会一直占用需要的依赖文件。无法进行覆盖替换,所以当主程序将文件下载完后。启动另一个可执行程序解压下载的zip包,完成后在启动主程序。
解压zip的可执行程序需要的依赖不可以和主程序共享。需要单独拥有一份。so 要在主程序的目录下建一个文件夹用于存放解压zip的程序和依赖。
所以需要编写另一个解压zip的可执行程序,zip是从服务器下载的更新文件,下载到主程序目录下将zip 解压后直接替换主程序的文件,
- 检查是否需要更新
- 编写更新程序替换旧文件
效果:
AppUpdate.h
#include <QMainWindow>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QJsonParseError>
#include <QJsonObject>
#include <QProgressBar>
#include <QPointer>
#include <QMessageBox>
#include <QApplication>
#include <QFileInfo>
#include <QProcess>class AppUpdate : public QMainWindow {
Q_OBJECTpublic:explicit AppUpdate(QWidget *parent = nullptr) : QMainWindow(parent) {//发起请求mPostRequest.post(QNetworkRequest(QUrl("http://127.0.0.1:8000/update/")), QByteArray());// 完成后触发信号connect(&mPostRequest, &QNetworkAccessManager::finished, [=](QNetworkReply *r) {if (r->error() == QNetworkReply::NoError) {QString mallJson = QString::fromUtf8(r->readAll());QJsonParseError jsonError{};QJsonDocument document = QJsonDocument::fromJson(mallJson.toUtf8(), &jsonError);if (jsonError.error == QJsonParseError::NoError) {QJsonObject mHosts = document.object();// 更新程序下载地址 由服务器返回 // 比如:http://127.0.0.1:8000/update/update.zipDownloadFileUrl = mHosts["url"].toString();// 获取的版本格式为 1.0.1 字符串已点分割,转intint newVersion = mHosts["version"].toString().split(".").join("").toInt();if (mVersion.split(".").join("").toInt() < newVersion) {// 询问是否需要更新软件int index = QMessageBox::information(this, "版本更新提示", "发现新版本 V 1.0.1 是否更新",QMessageBox::Ok | QMessageBox::No, QMessageBox::Ok);if (index == QMessageBox::No)return;// 下载插件mDownloadProgress->show();// 显示进度条mDownloadFile = new QFile(QCoreApplication::applicationDirPath() + "/update.zip");// 文件下载后存储路径直接下载到当前主程序目录下mDownloadFile->open(QIODevice::WriteOnly);//打开文件reply = mGetRequest.get(QNetworkRequest(QUrl(DownloadFileUrl)));// 下载请求connect(reply, &QIODevice::readyRead, [=] {//打开写入文件if (mDownloadFile) mDownloadFile->write(reply->readAll());}); //读取插件connect(&mGetRequest, &QNetworkAccessManager::finished, [=] {//插件下载完成QFileInfo fi;if (mDownloadFile) {const QString &OldName = mDownloadFile->fileName();fi.setFile(OldName);mDownloadFile->close();// 关闭文件mDownloadFile->reset();// 重置// 退出主程序 运行更新程序// 需要将下载的新文件替换已安装的旧文件 ,如果不退出程序,文件被主程序使用用无法替换if (QProcess::startDetached(QCoreApplication::applicationDirPath() + "/update/" + "update.exe"))// 如果成功打开更新程序QApplication::exit(0); // 退出主程序}});connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesRead, qint64 totalBytes) {//下载进度qreal progress = qreal(bytesRead) / qreal(totalBytes);mDownloadProgress->setValue(progress * 100);
// qDebug() << QString::number(progress * 100, 'f', 2) << "% " << bytesRead / (1024 * 1024) << "MB" << "/"<< totalBytes / (1024 * 1024) << "MB";});}}}});}private:const QString mVersion = "1.0.0";// 当前版本QNetworkAccessManager mPostRequest;// Post请求QNetworkAccessManager mGetRequest;// Get请求QPointer<QNetworkReply> reply;QFile *mDownloadFile;// 保存文件QProgressBar *mDownloadProgress = new QProgressBar(this);// 下载进度条QString DownloadFileUrl;
};
解压zip 的可执行文件 需要在.por 文件中加入 QT += core gui gui-private
update.h
#include <QDir>
#include <QApplication>
#include <private/qzipreader_p.h>
#include<QProcess>
int main(int argc, char *argv[])
{QApplication a(argc, argv);const QString &ZipPath = QCoreApplication::applicationDirPath();QDir Dir(ZipPath); Dir.cdUp();//上级目录QStringList pFiles = Dir.entryList(QDir::Files); //获取所有文件for (int i = 0; i < pFiles.length(); ++i) {if (pFiles[i].split(".").back() == "zip") {// 解压zip文件QZipReader reader(Dir.path()+"/"+pFiles[i]);// 将文件解压到主程序目录下 解压后会无提示覆盖主程序旧文件reader.extractAll(Dir.path());reader.close();QFile::remove(Dir.path()+"/"+pFiles[i]); // 删除文件break;}}// 完成后启动主程序QProcess::startDetached(Dir.path()+"/"+"main.exe");return 0;
}
用于解压zip覆盖主程序旧文件的可执行文件,其中依赖独立,不共享主程序的依赖。
QT 实现软件在线更新功能相关推荐
- fpga在线升级 linux_以Flash控制器为核心的FPGA在线更新功能实现设计流程介绍
0 引言 近些年来,由于其灵活可配置性及成本的降低,现场可编程门阵列(Field Programmable Gate Array,FPGA)在嵌入式系统中应用越来越广泛,不论产品的初期研发或是后期维护 ...
- qt实现锁屏功能,即点击锁屏按钮后再点击界面则无效
qt实现锁屏功能,就像我们在使用视频软件的时候,会有一个锁的图标,点击后屏幕就不会被误触. 我想要实现的功能是:在点击了右下角的锁的图标之后,界面上的内容就不能点击了,也就是点击关闭是没有响应的,这样 ...
- 终端软件升级功能开发_5个很棒的终端技巧可帮助您升级为开发人员
终端软件升级功能开发 There are plenty of beginner tutorials around that help you learn command line basics, su ...
- 大白菜软件常用功能介绍
大白菜软件常用功能介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.刻录光盘介绍 1.选择你需要的刻录的光盘 2.点击刻录光盘 3.确认之后点击刻录 4.等待刻录完成 转载于 ...
- 用Qt写软件系列五:一个安全防护软件的制作(2)
引言 在上一篇中讲述了主窗体的创建和设计.主窗体的无边框效果.阴影效果.拖动事件处理.窗体美化等工作在前面的博客中早就涉及,因此上篇博文中并未花费过多笔墨.这一篇继续讲述工具箱(Tool Button ...
- Qt多文件传输功能实现及方法概述
Qt多文件传输功能实现 前言 代码实现概述 客户端代码实现 服务端代码 效果展示 结论 前言 本次设计主要是为了功能上的实现,因此对于ui界面的设计都是怎么简单怎么来的,主要的功能就是实现多个文件的发 ...
- 推荐+1置顶+1(分享、讨论、实现)通用软件注册功能之建立有效的软件保护机制...
推荐+1置顶+1(分享.讨论.实现) 通用软件注册功能之建立有效的软件保护机制 众所周知,一些共享软件往往提供给使用者的是一个功能不受限制的限时使用版,在试用期内使用者可以无限制的使用软件的全部功能( ...
- ug链轮设计软件_正版UG软件,UG软件代理,正版UG软件模块功能介绍
身处制造业的朋友们都知道,制造业离不开二维软件和三维软件,三维软件中尤其是UG软件因功能最强大,模块最全面而闻名,广泛应用于:CAE(结构有限元分析,热仿真,应力仿真,TMG仿真),CAD(产品设计, ...
- Android设备新型恶意软件,融合银行木马、键盘记录器和移动勒索软件等功能
2019独角兽企业重金招聘Python工程师标准>>> 网络犯罪分子目前正在开发一种针对Android设备的新型恶意软件,它融合了银行木马.键盘记录器和移动勒索软件的功能. 根据来自 ...
最新文章
- 开发者数量2025年预计破亿,GitHub最新年度报告来啦!
- VS2012生成ReactOS的VS工程失败(三)和 “ cl is not able to compile a simple test program“错误
- linux挂载固硬盘装,linux下安装新硬盘并挂载mount
- android8组windows10,微软正式开放Win10新功能:在PC端运行Android应用
- [机器学习-原理及实现篇]线性回归-最小二乘法
- 怎么让Go Modules使用私有依赖模块
- java最小泛型demo
- 游戏计算机lnv10,Win10日文游戏乱码转换工具(Locale Emulator)
- 计算机电源风扇安装方法,机箱风扇怎么装 电脑机箱风扇电源线接法
- win7万能声卡驱动_我把一台PC的操作系统从win7换成了win10,它真的很棒!
- 一周学习荟萃(TED,知识,教育,笑话,鸡汤)
- 【Java---数据结构】栈(Stack)
- 怎么判断滤波器的低通、高通和带通?
- Ez-USB FX3开发板的使用
- STM32学习笔记(13)——模数转换ADC
- Virtual DOM 的实现原理
- msconfig运行不了的解决方案
- 八皇后问题理解与解决
- 【STM32+cubemx】0025 HAL库开发:唯一ID获取和简单的程序加密
- 数字货币即将面世 蹭“数字货币”热度套路频现
热门文章
- 从烧录系统开始Jetson Nano无人车开发记录
- Freescale MC9S12G128 GPIO
- 如何计算服务器的性能负载?
- das nas san rain2.0+
- 简明易懂的数据库入门教程
- springside showcase mysql_搭建SpringSide示例showcase的eclipse运行环境
- 元宇宙未启,身份认证先行
- 原码 反码 换算工具 补码_原码,反码,补码相互转换在线计算器_三贝计算网_23bei.com...
- 操作系统进程状态模型
- python创建sqlite3数据库_Python连接SQLite数据库