在客户端软件开发过程中,有时候会设计到客户端软件版本的升级问题,客户端有个守护进程或者在客户端启动的时候,服务器返回一个版本号,这时候,需要通过返回的版本号去判断是否需要升级,从而达到升级的目的。
现在,本人在开发过程中写的一个客户端软件版本比较的类,与大家分享,如果代码有什么问题,欢迎大家指正。
好了,直接上代码。
ClientVersionMgr.h
#pragma once
#include <iostream>
#include <string>
// 客户端版本管理类
class ClientVersionMgr
{
public:
enum COMPARE_RESULT
{
NO_NEED_UPATE = 0,
HAVE_MORE_NEW_VERSION = 1,
NEED_FORCE_UPDATE = 2
};
/**
* @brief ClientVersionMgr默认构造函数
* @param[in] none
* @author long.an@quanshi.com
* @date 2013-08-03 17:46:12
*/
ClientVersionMgr(void);
/**
* @brief ClientVersionMgr构造函数
* @param[in] strVersion 版本号字符串
* @author long.an@quanshi.com
* @warning strVersion须为合法的版本格式:如a.b.c.d\n 如果不合法,将不做处理,将版本号作为1.0.0.0处理。
* @date 2013-08-03 17:46:12
*/
ClientVersionMgr(std::string strVersion);
public:
/**
* @brief ClientVersionMgr析构函数
* @author long.an@quanshi.com
* @date 2013-08-03 17:50:22
*/
~ClientVersionMgr(void);
public:
/**
* @brief 检测是否需要更新版本
* @param[in] MaxVersion 服务器支持的最高版本号
* @param[in] MinVersion 服务器支持的最小版本号
* @param[in] IgnoreBuild_Number 是否忽略编译版本号,默认忽略
* @return NO_NEED_UPATE 无需更新
* @return HAVE_MORE_NEW_VERSION 检测到有新版本
* @return NEED_FORCE_UPDATE 必须更新,否则不可用
* @author An Long
* @date 2013-07-29 18:06:49
*/
int CheckUpgrade(const ClientVersionMgr& MaxVersion, const ClientVersionMgr& MinVersion, bool IgnoreBuild_Number = true);
/**
* @brief 从string中获得版本号
* @param[in] strVersion 版本号
* @return ClientVersionMgr对象
* @author long.an@quanshi.com
* @date 2013-07-29 18:13:30
*/
bool ParseVersionByString(const std::string& strVersion, ClientVersionMgr& Version);
/**
* @brief 设置版本号
* @param[in] strVersion 版本号字符串
* @return none
* @author long.an@quanshi.com
* @date 2013-08-03 17:50:55
*/
void SetClientVersion(std::string strVersion);
/**
* @brief 获取版本号字符串
* @param[in] none
* @return 版本号字符串
* @author long.an@quanshi.com
* @date 2013-08-03 17:51:57
*/
const std::string GetClientVersion() const;
/**
* @brief 小于操作
* @param[in] Version 小于比较的右值,this为左值
* @return true this小于Version的版本号
* @author long.an@quanshi.com
* @date 2013-08-03 17:52:50
*/
bool operator <(const ClientVersionMgr& Version);
/**
* @brief 大于操作
* @param[in] Version 大于比较的右值,this为左值
* @return true this大于Version的版本号
* @author long.an@quanshi.com
* @date 2013-08-03 17:52:50
*/
bool operator >(const ClientVersionMgr& Version);
/**
* @brief 等于操作
* @param[in] Version 等于比较的右值,this为左值
* @return true this等于Version的版本号
* @author long.an@quanshi.com
* @date 2013-08-03 17:52:50
*/
bool operator ==(const ClientVersionMgr& Version);
public:
unsigned int Major_Version_Number; // 主版本号
unsigned int Minor_Version_Number; // 子版本号
unsigned int Revision_Number; // 修正版本号
unsigned int Build_Number; // 编译版本号
};
#include "StdAfx.h"
#include "ClientVersionMgr.h"
ClientVersionMgr::ClientVersionMgr(void)
{
Major_Version_Number = 1;
Minor_Version_Number = 0;
Revision_Number = 0;
Build_Number = 0;
}
ClientVersionMgr::ClientVersionMgr(std::string strVersion)
{
if(!ParseVersionByString(strVersion, *this))
{
Major_Version_Number = 1;
Minor_Version_Number = 0;
Revision_Number = 0;
Build_Number = 0;
}
}
ClientVersionMgr::~ClientVersionMgr(void)
{
}
/**
* @brief 检测更新
* @param[in] MaxVersion 服务器支持的最高版本号
* @param[in] MinVersion 服务器支持的最小版本号
* @param[in] IgnoreBuild_Number 是否忽略编译版本号,默认忽略
* @return
* @req MeetMeMobile1.0-Outlook-05-001
* @author long.an@quanshi.com
* @date 2013-07-29 18:06:49
*/
int ClientVersionMgr::CheckUpgrade(const ClientVersionMgr& MaxVersion, const ClientVersionMgr& MinVersion, bool IgnoreBuild_Number)
{
if (IgnoreBuild_Number == true)
{
ClientVersionMgr _MaxVersion(MaxVersion);
ClientVersionMgr _MinVersion(MinVersion);
_MaxVersion.Build_Number = this->Build_Number;
_MinVersion.Build_Number = this->Build_Number;
if (*this == _MaxVersion)
{
return NO_NEED_UPATE;
}
else if(*this < _MaxVersion && (*this > _MinVersion || *this == _MinVersion))
{
return HAVE_MORE_NEW_VERSION;
}
else if (*this < _MinVersion)
{
return NEED_FORCE_UPDATE;
}
}
else
{
if (*this == MaxVersion)
{
return NO_NEED_UPATE;
}
else if(*this < MaxVersion && (*this > MinVersion || *this == MinVersion))
{
return HAVE_MORE_NEW_VERSION;
}
else if (*this < MinVersion)
{
return NEED_FORCE_UPDATE;
}
else
{
return NEED_FORCE_UPDATE;
}
}
}
/**
* @brief 从string中获得版本号
* @param[in] strVersion 版本号
* @return ClientVersionMgr对象
* @req MeetMeMobile1.0-Outlook-05-001
* @author long.an@quanshi.com
* @date 2013-07-29 18:13:30
*/
bool ClientVersionMgr::ParseVersionByString(const std::string& strVersion, ClientVersionMgr& Version)
{
if (strVersion.empty())
{
return false;
}
size_t nPos1 = strVersion.find('.',0);
size_t nPos2 = strVersion.find('.',nPos1+1);
size_t nPos3 = strVersion.find('.',nPos2+1);
if (nPos1 == -1 || nPos2 == -1)
{
return false;
}
Version.Major_Version_Number = atoi(strVersion.substr(0,nPos1).c_str());
Version.Minor_Version_Number = atoi(strVersion.substr(nPos1+1,nPos2-nPos1).c_str());
Version.Revision_Number = atoi(strVersion.substr(nPos2+1,nPos3-nPos2).c_str());
if (nPos3 != -1)
{
Version.Build_Number = atoi(strVersion.substr(nPos3+1,strVersion.length()-nPos3).c_str());
}
else
{
Version.Build_Number = 0;
}
return true;
}
void ClientVersionMgr::SetClientVersion(std::string strVersion)
{
ParseVersionByString(strVersion.c_str(), *this);
}
const std::string ClientVersionMgr::GetClientVersion() const
{
std::string strVersion;
char szBuffer[100] = {0};
sprintf(szBuffer, "%d.%d.%d.%d", Major_Version_Number, Minor_Version_Number, Revision_Number, Build_Number);
return std::string(szBuffer);
}
bool ClientVersionMgr::operator <(const ClientVersionMgr& Version)
{
// Major_Version_Number <
if (this->Major_Version_Number < Version.Major_Version_Number)
{
return true;
}
else if (this->Major_Version_Number > Version.Major_Version_Number) // Major_Version_Number >
{
return false;
}
else // Major_Version_Number =
{
// compare Minor_Version_Number
// condition: the Major_Version_Number of this version has equal Major_Version_Number of version then Minor_Version_Number<
if ( this->Minor_Version_Number < Version.Minor_Version_Number )
{
return true;
}
else if (this->Minor_Version_Number > Version.Minor_Version_Number)// Minor_Version_Number >
{
return false;
}
else
{
if ( this->Revision_Number < Version.Revision_Number )
{
return true;
}
else if (this->Revision_Number > Version.Revision_Number)// Minor_Version_Number >
{
return false;
}
else
{
if ( this->Build_Number < Version.Build_Number )
{
return true;
}
else
{
return false;
}
}
}
}
}
bool ClientVersionMgr::operator >(const ClientVersionMgr& Version)
{
if (*this < Version || *this == Version)
{
return false;
}
else
{
return true;
}
}
bool ClientVersionMgr::operator ==(const ClientVersionMgr& Version)
{
if ( Major_Version_Number == Version.Major_Version_Number
&& Minor_Version_Number == Version.Minor_Version_Number
&& Revision_Number == Version.Revision_Number
&& Build_Number == Version.Build_Number )
{
return true;
}
else
{
return false;
}
}
测试代码
int _tmain(int argc, _TCHAR* argv[])
{
std::string strVersion1 = "1.0.0.0";
std::string strVersion2 = "2.4.3.4254";
ClientVersionMgr MaxVersion(strVersion2);
ClientVersionMgr MinVersion(strVersion1);
ClientVersionMgr CurVersion("2.0.4.3");
// 忽略编译版本号
int nRet = CurVersion.CheckUpgrade(MaxVersion, MinVersion, true);
if (ClientVersionMgr::HAVE_MORE_NEW_VERSION == nRet)
{
printf("存在新版本");
}
else if (ClientVersionMgr::NEED_FORCE_UPDATE == nRet)
{
printf("当前版本已不可用,需要升级后才可以使用");
}
else
{
printf("已经是最新的版本");
}
return 0;
}