1、自动升级需要实现两个exe程序的交替启动,需要一个主程序和一个升级程序;在一个解决方案中创建两个项目,一个是你的主程序,另一个为你的升级程序;第二个程序创建选择添加到解决方案,同时选中你要添加的位子(即主程序路径)。
2、创建成功后的解决方案;Agent为我的升级程序,AutoUpdate为我的主程序。
3、创建本地版本文件和服务端版本文件;
本地版本文件:
VersionInfo.ini
[INIURL]
iniurl=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/AgentVersionInfo.ini
[MAINVER]
mainver=1.0
[VERDATE]
verdate=2018-03-09 09:36:52
[AUTHOR]
author=kung
服务端版本文件:
AgentVersionInfo.ini
[INIURL]
iniurl=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/AgentVersionInfo.ini
[MAINVER]
mainver=2.0
[VERDATE]
verdate=2018-03-09 09:36:52
[AUTHOR]
author=kung
[FILECOUNT]
filecount=7
[FILENAME]
filename1=AutoUpdate.exe
filename2=test/a6.txt
filename3=test/a7.txt
filename4=test/a8.txt
filename5=test/a9.txt
filename6=test/test/a10.txt
filename7=test/test/a11.txt
[FILEURL]
fileurl1=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/AutoUpdate.exe,B84DACA51346BBD1F074C97F60ACAEE9
fileurl2=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/a6.txt,1B6D5D3EE41909A1BD0880F72890B5F7
fileurl3=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/a7.txt,1B6D5D3EE41909A1BD0880F72890B5F7
fileurl4=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/a8.txt,1B6D5D3EE41909A1BD0880F72890B5F7
fileurl5=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/a9.txt,1B6D5D3EE41909A1BD0880F72890B5F7
fileurl6=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/test/a10.txt,1B6D5D3EE41909A1BD0880F72890B5F7
fileurl7=http://220.231.141.28:8088/HDMFCUPDATE/AutoUpdate/20180301/test/test/a11.txt,1B6D5D3EE41909A1BD0880F72890B5F7
4、再主程序中添加代码,读取服务端的升级文件的版本号和版本文件进行比对;如果本地版本低的话,启动升级程序进行文件下载更新,否则不更新,通过线程的方式检查版本。
VersionUpdate.h
#pragma once
class VersionUpdate
{
public:
VersionUpdate(void);
~VersionUpdate(void);
//自动更新线程
static UINT ThreadCheckVer(LPVOID pParam);
//下载包含更新版本号的配置文件
static INT DownloadIniFile(CString strUrl);
//下载指定地址的文件
static INT DownloadFile(const CString strUrl,const CString strSavePath);
};
VersionUpdate.cpp
#include "StdAfx.h"
#include "VersionUpdate.h"
#include
#include
#define BUF_SIZE 2048
#define WM_UPDATE WM_USER+100
VersionUpdate::VersionUpdate(void)
{
}
VersionUpdate::~VersionUpdate(void)
{
}
//自动更新线程
UINT VersionUpdate::ThreadCheckVer(LPVOID lpParam)
{
CString strFileName_ini,strControlName;
//从配置文件读入当前版本号
char str[MAX_PATH];
GetModuleFileName(NULL,str,128);
CString exePath;
exePath = str;
CString programFolder;
programFolder = exePath.Mid(0,exePath.ReverseFind('\\'))+"\\";
//char pBuf[MAX_PATH];
//GetCurrentDirectory(MAX_PATH,pBuf);
//strcat_s(pBuf,"\\VersionInfo.ini");
strFileName_ini = programFolder + "VersionInfo.ini";
//获取当前配置文件的版本号
::GetPrivateProfileString("MAINVER","mainver",NULL,strControlName.GetBuffer(128),128,strFileName_ini);
strControlName.ReleaseBuffer();
double flCurVer = atof(strControlName); //保存当前版本号
//获取下载配置文件的地址
strControlName = "";
::GetPrivateProfileString("INIURL","iniurl",NULL,strControlName.GetBuffer(MAX_PATH),MAX_PATH,strFileName_ini);
strControlName.ReleaseBuffer();
CString strUrl = strControlName;
if (strUrl.GetLength() == 0){
AfxMessageBox("VersionInfo.ini文件有误,请手动下载新版本!");
return 0;
}
//下载包含更新版本号的配置文件
INT DownloadFileResult = DownloadIniFile(strUrl);
if(DownloadFileResult != 0){
//AfxMessageBox("检测新版本失败!如果软件不能使用请手动下载更新!");
return 0;
}
//从下载来的配置文件读入最新版本号
strFileName_ini.Replace("VersionInfo.ini","AgentVersionInfo.ini");
::GetPrivateProfileString("MAINVER","mainver",NULL,strControlName.GetBuffer(128),128,strFileName_ini);
strControlName.ReleaseBuffer();
double flNewVer = atof(strControlName);
//对比版本号 如果大于本地版本就启动更新程序进行更新 更新成功就写入新版本到pz.ini里
if( flNewVer > flCurVer){
//启动UpDate.exe来更新Dll
char pBuf[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pBuf);
strcat_s(pBuf,"\\Agent.exe");
CString strPath = pBuf;
HINSTANCE hID = ShellExecuteA(NULL,"open",strPath,NULL,NULL,SW_SHOWNORMAL);
if ((int)hID <= 32)
{
AfxMessageBox("程序目录下缺少升级程序Agent.exe!,请重新下载完整版本!");
return 0;
}
//关闭本程序
ExitProcess(0);
}else{
::DeleteFile(strFileName_ini); //删除下载来的配置文件
}
return 0;
}
//下载包含更新版本号的配置文件
INT VersionUpdate::DownloadIniFile(CString strUrl)
{
CString strFileName_ini;
char pBuf[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pBuf);
strcat_s(pBuf,"\\AgentVersionInfo.ini");
strFileName_ini = pBuf;
char buf[BUF_SIZE] = {0};
char url[MAX_PATH];
strcat_s(url,strUrl);
return DownloadFile(url,strFileName_ini);
}
//下载指定地址的文件
/*
0:成功下载保存
-1:URL不正确
-2:建立网络连接失败
-3:向服务器发起GET请求失败
-4:服务器不接受请求
-5:参数一不能为空
-6:参数二不能为空
-7:保存文件时创建或写入文件失败
*/
INT VersionUpdate::DownloadFile(const CString strUrl,const CString strSavePath)
{
//检查传入的两个参数
if (strUrl.IsEmpty())
return -5;
if (strSavePath.IsEmpty())
return -6;
unsigned short nPort; //用于保存目标HTTP服务端口
CString strServer, strObject; //strServer用于保存服务器地址,strObject用于保存文件对象名称
DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号
//解析URL,获取信息
if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort)){
//解析失败,该Url不正确
return -1;
}
//创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete
CInternetSession intsess;
CHttpFile *pHtFile = NULL;
CHttpConnection *pHtCon = NULL;
intsess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 1000 * 20); //连接超时
intsess.SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000); //两次重试之间的间隔时间
intsess.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1); // 2次重试
intsess.SetOption(INTERNET_OPTION_SEND_TIMEOUT,6000); //发送请求的超时时间
intsess.SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT,6000); //接受数据的超时时间
try{
//建立网络连接
pHtCon = intsess.GetHttpConnection(strServer,nPort);
if(pHtCon == NULL){
//建立网络连接失败
intsess.Close();
return -2;
}
//发起GET请求
pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject);
if(pHtFile == NULL)
{
//发起GET请求失败
intsess.Close();
delete pHtCon;
pHtCon = NULL;
return -3;
}
//提交请求
pHtFile->SendRequest();
//获取服务器返回的状态号
pHtFile->QueryInfoStatusCode(dwRet);
if (dwRet != HTTP_STATUS_OK){
//服务器不接受请求
intsess.Close();
delete pHtCon;pHtCon = NULL;
delete pHtFile;pHtFile = NULL;
return -4;
}
}catch (CInternetException* e){
e->Delete();
intsess.Close();
delete pHtCon;pHtCon = NULL;
delete pHtFile;pHtFile = NULL;
return -2;
}
//获取文件大小
UINT nFileLen = (UINT)pHtFile->GetLength();
DWORD dwRead = 1; //用于标识读了多少,为1是为了进入循环
//创建缓冲区
CHAR *szBuffer = new CHAR[nFileLen+1];
TRY {
//创建文件
CFile PicFile(strSavePath,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
while(dwRead>0)
{
//清空缓冲区
memset(szBuffer,0,(size_t)(nFileLen+1));
//读取到缓冲区
dwRead = pHtFile->Read(szBuffer,nFileLen);
//写入到文件
PicFile.Write(szBuffer,dwRead);
}
//关闭文件
PicFile.Close();
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
}
CATCH(CFileException,e)
{
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
return -7; //读写文件异常
}
END_CATCH
return 0;
}
5、Agent升级程序需要添加一个列表对话框,用于显示文件下载进度;
6、Agent程序先根据现在的升级版本文件,显示需要更新的文件列表、文件大小,读取版本文件的内容,同时获取本地文件的MD5,比对MD5,如果不同则根据版本文件的地址下载覆盖本地文件,同时显示下载进度;升级完成删除下载的远端版本文件,然后启动主程序,关闭升级程序;
7、更多源码您可以下载查看。
源码下载地址:点击打开链接
仅此供给大家,在大家有这方面的需求时,少走弯路!如果对大家有用,请大家多多点赞支持!