mfc 更新服务器文件,MFC程序版本自动升级更新
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_SIZE2048
#define WM_UPDATEWM_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、更多源码您可以下载查看。
源码下载地址:点击打开链接
仅此供给大家,在大家有这方面的需求时,少走弯路!如果对大家有用,请大家多多点赞支持!
mfc 更新服务器文件,MFC程序版本自动升级更新相关推荐
- c/s程序版本自动升级的问题,如何判断client端版本号是否最新,然后从指定ftp服务器down...
c/s程序版本自动升级的问题,如何判断client端版本号是否最新,然后从指定ftp服务器down http://blog.csdn.net/delphizhou/article/details/30 ...
- 火绒能更新服务器系统么,火绒自动升级频率是怎么样的?
[1]2020-09-05 19:00:38,其他,升级日志,自动更新成功,版本号:5.0.52.0 [2]2020-09-04 19:00:38,其他,升级日志,自动更新成功,版本号:5.0.52. ...
- 如何刷新微信服务器小程序版本,微信小程序版本自动更新
最近在做一个小程序每次更新版本之后都需要删除小程序,再次扫码进入才可以看到新版本,接下来吾爱编程为大家介绍一下微信小程序版本自动更新的方法,有需要的小伙伴可以参考一下: 1.启动机制: (1).热启动 ...
- 微信小程序版本自动更新用户感知提示方案总结
微信小程序版本自动更新用户感知提示方案总结 需求背景 最近基于uniapp开发微信小程序上线后,在迭代版本后期望自动更新提示. 使感知. 解决方案 使用全局唯一的对象: updateManager. ...
- C#实现程序的版本在线升级更新
文章目录 背景 代码 下载地址 设置到的知识点 参考文献 背景 最近在做开发的时候,需要程序有自动版本升级的功能.特此记录下整个过程. 代码 注意事项: 服务器端需要上传XML配置文件和待下载的软件 ...
- 如何通过蒲公英实现iOS版本自动提示更新,省去频繁打内测版本发链接给同事老板
一:xcode项目中需要做的操作 1.代码中设置bulid号 2.在xcode中添加指定脚本(确保每次打版bulid号会自动+1,这样可以确保每次打包的bulid号>蒲公英上曾经打版的号) if ...
- Selenium根据Chrome浏览器版本自动下载/更新驱动chromedriver.exe
个人经常使用到selenium来控制浏览器进行相关的操作,但是Chrome浏览器经常会自动更新,导致已有的驱动程序chromedriver.exe失效,需要重新下载. 以前尝试过禁止Chrome浏览器 ...
- python 文件更新_使用Python批量更新服务器文件【新手必学】
买了个Linux服务器,Centos系统,装了个宝塔搭建了10个网站,比如有时候要在某个文件上加点代码,就要依次去10个文件改动,虽然宝塔是可视化页面操作,不需要用命令,但是也麻烦,虽然还有git的h ...
- maven pom java版本_Maven更新POM中的JDK版本(比如更新为JDK1.8)
默认POM如果不指定JDK版本为1.5,而有些项目需要使用泛型这些,就必须使用1.8版本的JDK,所以需要手动修改POM. 打开pom.xml文件修改,增加如下配置节点: [...] [...] or ...
最新文章
- SAP PM 入门系列12 - IW32 下达一个维护订单
- 用vs2005 开发arcims htmlViewer
- JAVA I/O操作那些事之标准I/0
- Ch3101-阶乘分解【数论,质因数分解】
- django 模型类的常见字段约束,以及filter 过滤和查询
- [C# 网络编程系列]专题九:实现类似QQ的即时通信程序
- 简单获取PNG免扣素材,提升设计效率
- Windows 系统彻底卸载 SQL Server 通用方法
- fast-DTW算法
- 【论文解读】MV3D-Net、AVOD-Net用于自动驾驶的多视图3D目标检测网络
- 第十一周助教心得体会
- 初学Arduino环境下WeMos D1制造简单智能垃圾桶项目(蜂鸣器、	SG90舵机、超声波模块)
- 高德地图打点获取点的坐标和名称
- JS作用域和自由变量
- 清除IDM假冒序列号及重置试用期
- Python实现倒计时程序
- vue3中使用jszip压缩文件
- C语言中耳熟能详的printf与scanf
- 接口自动化测试用例详解
- Django captcha验证码应用【亲测可用】
热门文章
- anaconda成功安装fasttext后,无法导入的情况
- keil5按F12调不出头文件中函数
- matlab期中考试卷,matlab期末考试试卷及答案.doc
- spring整合atomikos实现分布式事务的方法示例_分布式事务一:基于数据库原生分布式事务方案实现...
- FileZilla软件下载使用简易教程
- CSS和HTML面试题
- day9 java的实例语句块和代码执行顺序
- 数据库 统计数据收集 有什么作用_《原神》荒山孤剑录2/5收集汇总 荒山孤剑录作用是什么...
- 帮助文档的制作(控制台、eclipse两种方式)
- 一个字形容大数据_嘉禾数据科学分享(八):一个大数据专业教师眼里的大数据