实现软件更新,需要写入本地软件的版本号,并读取出来,与服务器版本号相比较,决定是否进行软件的更新。
1.写入版本信息:
写入一个rc文件,并将其导入到Qt工程中。
在Qt工程中,利用RC_FILE+=version.rc 导入工程
QT+VS编译时,利用cmake导入工程即可.
代码如下:
IDI_ICON1 ICON DISCARDABLE "LYL/icons/tubiao.ico"
#if defined(UNDER_CE)
#include <winbase.h>
#else
#include <winver.h>
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1.0.0.0
PRODUCTVERSION 1.0.0.0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404b0"
BEGIN
VALUE "CompanyName", "...公司\0"
VALUE "FileDescription", "...\0"
VALUE "FileVersion", "1.0.0.0\0"
VALUE "ProductVersion", "1.0.0.0\0"
VALUE "LegalCopyright", "版权所有 (C)...公司\0"
VALUE "LegalTrademarks", "...公司\0"
VALUE "OriginalFilename", "Version.exe\0"
VALUE "ProductName", "...查看系统\0"
VALUE "InternalName", "Version.exe\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
效果如下:
2.读取软件的版本号:
首先需要引入三个库
#include <windows.h>
#include <winver.h>
#pragma comment(lib, "Version")
写入读取版本号的方法:
QString GetFileVertion(QString fullName)
{
QString result = "";
char *pData = nullptr;
DWORD dwlen = GetFileVersionInfoSize(fullName.toStdString().c_str(), 0);
if (0 == dwlen) {
return result;
}
pData = new char[dwlen + 1];
BOOL bSuccess = GetFileVersionInfo(fullName.toStdString().c_str(), 0, dwlen, pData);
if (false == bSuccess) {
delete pData;
return result;
}
LPVOID lpBuffer = nullptr;
UINT uLen = 0;
//获取语言页和代码页
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
bSuccess = VerQueryValue(pData, (TEXT("\\VarFileInfo\\Translation")), (LPVOID*)&lpTranslate, &uLen);
if (false == bSuccess) {
delete pData;
return result;
}
QString str1, str2;
str1.setNum(lpTranslate->wLanguage, 16);
str2.setNum(lpTranslate->wCodePage, 16);
str1 = "000" + str1;
str2 = "000" + str2;
QString verPath = "\\StringFileInfo\\" + str1.right(4) + str2.right(4) + "\\FileVersion";
bSuccess = VerQueryValue(pData, (verPath.toStdString().c_str()), &lpBuffer, &uLen);
if (false == bSuccess) {
delete pData;
return result;
}
result = QString::fromLocal8Bit((char *)lpBuffer);
if (nullptr != pData) {
delete pData;
}
return result;
}
3.版本号的调用比较:
int checkVersion()
{
QString myVersion = GetFileVertion("Vincialign.exe");
int retValue = 0;
bool netIsConnected = checkNetworkConnected();
if (false == netIsConnected) {
return retValue;
}
QVersionNumber myVersionNumber = QVersionNumber::fromString(myVersion);
QString serverVersion = getVersionFromServer();
QVersionNumber serverVersionNumber = QVersionNumber::fromString(serverVersion);
if (true == serverVersionNumber.isNull()) {
return retValue;
}
int compareVersion = QVersionNumber::compare(myVersionNumber, serverVersionNumber);
if (0 > compareVersion) {
CustomMsgBox* custommsgbox = new CustomMsgBox(NULL, updTitle, updContent, QMessageBox::Cancel | QMessageBox::Ok);
int ret = custommsgbox->exec();
switch (ret) {
case QMessageBox::Ok:
QDesktopServices::openUrl(QUrl(strCompanyWebSite));
retValue = 1;
break;
case QMessageBox::Cancel:
retValue = 0;
break;
}
}
return retValue;
}
myVersion为读取的当前版本号,serverVersion为服务器提供的版本号。将两个QString类型转化为QVersionNumber类型
利用int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2)
方法返回值<0,v2版本号大于v1版本号,进行更新操作。
这里利用
QDesktopServices::openUrl(QUrl(strCompanyWebSite));
打开网址进行下载更新包,并利用exit(0);退出主程序.
bool checkNetworkConnected()
{
QNetworkConfigurationManager mgr;
return mgr.isOnline();
}
利用QNetworkConfigurationManager 进行判断网络是否连接。