也可以参照本博主另外一篇:Qt 实现软件自动更新
一、自动更新程序流程
- 加载本地配置文件获取获取保存的版本号
- 每次启动程序,首先从服务器请求最新的版本信息文件(包括版本号,压缩包下载地址,更新时间,更新说明)
- 解压下载的文件获取服务器版本号,与本地版本号进行比较,如果高于本地,就下载压缩文件
- 解压缩程序压缩包
- 更新本地版本号,启动压缩包程序,退出当前自动更新程序
二、代码实现
1. 加载配置文件(采用TinyXml解析xml文件)
TinyXml详细用法可参考:C++库(TinyXml)的安装和使用
XMl 文件内容
<?xml version="1.0" encoding="utf-8" ?>
<AutoUpdate>
<Version>V4.0.0.2</Version>
<Url>https://eval.zhihuiyunji.com/riskclient_update/</Url>
<WindowIcon>:/AutoUpdate/Resources/RiskControlClient_24.png</WindowIcon>
<RunExe>\RiskClient\RiskClient.exe</RunExe>
</AutoUpdate>
Configer 头文件
#pragma once
#include "tinyxml/tinyxml.h"
#include <iostream>
#include <string>
#include <memory>
#include <vector>
using namespace std;
class StaticClass
{
private:
StaticClass();
StaticClass(const StaticClass&);
StaticClass& operator = (const StaticClass&);
};
class Configer : StaticClass
{
public:
~Configer() {
};
static bool Load();
static string FilePath();
static string FilePath_Cfg();
static bool LoadConfigFile();
static bool SaveVersion(const char *version);
static const string &GetVersion();
static const string &GetWindowIcon();
static const string &GetQurl();
static const string &GetRunExe();
private:
static string m_strVersion;
static string m_strIcon;
static string m_ptrQurl;
static string m_ptrRunExe;
};
cpp 文件
#include "configer.h"
#include "windows.h"
string Configer::m_strVersion;
string Configer::m_strIcon;
string Configer::m_ptrQurl;
string Configer::m_ptrRunExe;
string Configer::FilePath()
{
string strReturn;
HMODULE hModule = GetModuleHandle(NULL);
char pFileName[MAX_PATH] = {
0 };
::GetModuleFileNameA(hModule, pFileName, MAX_PATH);
string strModuleFullPath = pFileName;
size_t npos = strModuleFullPath.rfind("\\", strModuleFullPath.length());
if (npos != string::npos)
{
strReturn = strModuleFullPath.substr(0, npos);
}
return strReturn;
}
string Configer::FilePath_Cfg()
{
return FilePath() + "\\cfg.xml";
}
bool Configer::Load()
{
return LoadConfigFile();
}
bool Configer::LoadConfigFile()
{
std::shared_ptr<TiXmlDocument> doc_(new TiXmlDocument);
if (!doc_->LoadFile(FilePath_Cfg().c_str()))
{
std::cout << doc_->ErrorDesc() << std::endl;
return false;
}
TiXmlElement *root = doc_->FirstChildElement(); //获取根节点元素
if (root == NULL)
{
std::cerr << "Failed to load file:No curversion element." << std::endl;
doc_->Clear();
return false;
}
TiXmlElement *ptrVersion = root->FirstChildElement("Version");
if (ptrVersion != nullptr)
{
m_strVersion = ptrVersion->GetText();
}
else
{
std::cerr << "Load version error" << endl;
return false;
}
TiXmlElement *ptrUrl = root->FirstChildElement("Url");
if (ptrUrl != nullptr)
{
m_ptrQurl = ptrUrl->GetText();
}
else
{
std::cerr << "Load Qurl error" << endl;
return false;
}
TiXmlElement *ptrIcon = root->FirstChildElement("WindowIcon");
if (ptrIcon != nullptr)
{
m_strIcon = ptrIcon->GetText();
}
else
{
std::cerr << "Load WindowIcon error" << endl;
return false;
}
TiXmlElement *ptrRunExe = root->FirstChildElement("RunExe");
if (ptrRunExe != nullptr)
{
m_ptrRunExe = ptrRunExe->GetText();
}
else
{
std::cerr << "Load RunExe error" << endl;
return false;
}
return true;
}
bool Configer::SaveVersion(const char *version)
{
std::shared_ptr<TiXmlDocument> doc_(new TiXmlDocument);
if (!doc_->LoadFile(FilePath_Cfg().c_str()))
{
std::cout << doc_->ErrorDesc() << std::endl;
return false;
}
TiXmlElement *root = doc_->FirstChildElement(); //获取根节点元素
if (root == NULL)
{
std::cerr <<