桌面软件的智能更新MagicUpdate更新原理Word格式文档下载.docx
- 文档编号:22407346
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:22
- 大小:897.58KB
桌面软件的智能更新MagicUpdate更新原理Word格式文档下载.docx
《桌面软件的智能更新MagicUpdate更新原理Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《桌面软件的智能更新MagicUpdate更新原理Word格式文档下载.docx(22页珍藏版)》请在冰豆网上搜索。
4.1
更新模式...10
4.2
文件结构设计...10
4.2.1
服务器端文件信息...11
4.2.2
客户端文件信息ClientConfig结构...13
4.2.3
管理端文件信息ManagerConfig结构...14
4.2.4
宏说明及文件路径的计算...15
4.3
更新详细流程...16
4.3.1
管理端流程...16
4.3.2
客户端流程...17
4.4
客户端命令行...18
4.5
自我升级...19
5
小结...20
随着桌面软件文件的增多增大、版本升级频繁,有时因为改动了几个很小的几个dll文件,客户不得不从网站上重新下载整个安装包。
并且开发人员不得不从繁忙的工作中抽出大量的时间来维护版本的升级,导致开发成本增加、维护难度大等诸多问题。
有没有更完美的解决方案,来让软件自动升级到新版本呢?
答案当然是肯定的。
在当今网络技术技术迅速发展的时代,各个软件厂商各有各自的升级方法,现在我就谈谈我的解决方案。
关键技术:
●
多线程管理及交互
Http下载和断点续传
Ftp上传下载
Vc++对Xml读写解析
Md5算法
可执行程序Exe的相互嵌套
控件技术:
自定义三态树形控件CTreeCtrl和CListCtrl的互动
自定义CListCtrl,实现控件互嵌(进度条、编辑框、下拉框)
控件的自绘制
更新流程
1.
管理端上传当前版本的文件到服务器;
2.
客户端先自我更新,然后更新产品。
获取服务器信息,判断是否需要更新。
若需要则提示用户更新。
模块划分
界面展示
管理端:
客户端:
自动模式下的更新提示:
升级程序自我更新:
网络及多线程技术
多线程下载和断点续传
桌面软件的升级的方法有很多,如何自动的升级,当然少不了数据传输程序。
为了能够穿透防火墙在广域网使用我采用了基于http的下载。
原理大致如下:
创建一个的空文件,大小为需要下载的文件大小+零时数据大小;
创建多个线程,同时利用CreateFile共享写打开临时文件,移动文件指针到数据块开始区域;
3.
使用WinNetAPI,建立多个服务器连接,向服务器请求同一个文件的不同数据段的数据保存到同一个临时文件,并保存已下载的数据大小;
4.
数据都读完后,修改文件大小为原来大小。
若下载中途网络中断,下次下载时,则可以从尾部文件信息中获取已下载的大小,便于继续上一次的下载。
实现起来当然要考虑诸多细节方面,由于篇幅有限,就不详细说明。
利用WinNet函数很容易实现Ftp的上传下载,这里就不详细说明。
多线程与主线程(界面)的数据交互
交互的实现很复杂,用到了指针,回调函数,自己的消息队列等。
要全部讲清楚确不容易,我就简要介绍一下。
定义消息结构
typedefstruct_NotifyW3ctPara
{
int
nIndex;
//同一个下载文件中线程索引
UINTnNotityType;
//消息类型
DWORD
dwContent;
//通过StartDownload参数传入的值
LPVOID
lpNotifyData;
//消息数据
W3CT*pThread;
//下载模块指针
}NotifyW3ctPara;
定义消息存储数组和回调函数
typedefCArray<
NotifyW3ctPara,NotifyW3ctPara&
>
ArrayNotifyW3ctPara;
//消息通知回调函数
typedefvoid(*FunPtr_NotifyW3ct)(NotifyW3ctPara*);
处理消息
//添加消息
BOOLUpdateProcCtrl:
:
Add_NotifyPara(NotifyW3ctPara*pNotifyPara)
…
NotifyW3ctParanotifypara={0};
memcpy(&
notifypara,pNotifyPara,sizeof(NotifyW3ctPara));
m_csNotifyPara.Lock();
try{
m_aryNotifyW3ctPara.Add(notifypara);
}
catch(CMemoryException*e){
m_csNotifyPara.Unlock();
…
}
//清空消息
voidUpdateProcCtrl:
Clear_NotifyPara()
m_aryNotifyW3ctPara.RemoveAll();
m_csNotifyPara.Unlock();
//消息回调函数
Callback_Notify(NotifyW3ctPara*pNotifyPara)
AppSetting:
g_UpdateProcCtrl.Add_NotifyPara(pNotifyPara);
:
SendMessage(g_main_wnd->
GetSafeHwnd(),WM_TRANSFER_NOTIFY,NULL,NULL);
//消息处理
Deal_Notify(NotifyW3ctPara*pNotifyPara)
switch(pNotifyPara->
nNotityType)
{
caseNTD_THREAD_TANSFER_SIZE:
//在这里计算下载的速度、进度等
break;
//消息传输
LRESULTUpdateProcCtrl:
OnTransferNotify(WPARAMwParam,LPARAMlParam)
ArrayNotifyW3ctParaaryNotifyW3ctPara;
aryNotifyW3ctPara.Append(m_aryNotifyW3ctPara);
for(inti=0;
i<
aryNotifyW3ctPara.GetSize();
i++)
NotifyW3ctPara&
NotifyPara=aryNotifyW3ctPara.GetAt(i);
Deal_Notify(&
NotifyPara);
returnTRUE;
这里的消息处理大致就是这样,中间传输考虑很多同步互斥。
如果您对win的内核对象很了解,看这些代码相信不是什么难事,中间省略掉代码可以自己发挥了。
需要注意的是,多线程处理时线程间通信、交互以及取消线程都应该是安全的,不要使用TerminateThread,TerminateProcess等这些不安全的API,如果使用了他们,那么你的程序执行结果将是不可预料的。
更新细节
更新模式
更新模式分为MD5比较和文件版本号比较
MD5比较,即先计算文件的md5值,根据md5值判断文件是否变化;
版本号比较,即直接判断文件版本号是否是最新
文件结构设计
文件信息分为三个部分:
客户端信息、管理端信息、服务器端信息。
服务器端信息又分为状态信息和文件信息。
服务器端文件信息
4.2.1.1服务器状态信息ServerStatus结构
4.2.1.2
服务器文件信息ServerConfig结构
客户端文件信息ClientConfig结构
管理端文件信息ManagerConfig结构
宏说明及文件路径的计算
服务器端宏说明
(?
ServerDir)
-和服务器配置文件同一目录
ServerRoot)
-根目录
None)
-空
客户端宏说明
LocalFullPathName)-本地绝对路径,ExecuteCommand中用
LocalDir)
-和本地配置文件同一目录
以后可能会添加支持系统环境变量
例如:
如果服务器配置文件地址为:
http:
//localhost/update/ServerConfig.xml,则
ServerDir)=http:
//localhost/update/,
ServerRoot)=http:
//localhost/
服务器端文件真实地址计算方法:
如果server_root="
None)"
,则<
ServerPathName/>
表示真实地址,如果含有"
//"
表示绝对地址,否则应加上(?
ServerDir),等于(?
ServerDir)/<
;
ServerDir)"
,则(?
表示真实地址;
ServerRoot)"
ServerRoot)/<
支持的节点:
ServerPathName,ExecuteCommand
本地路径计算方法类似。
LocalPathName
文件比较方法分为MD5法和版本号比较法。
当为版本号比较时,将配置文件LocalPathName换成绝对路径,再比较版本号。
此时,文件路径中请不要包含"
."
和"
.."
,否则比较路径会不正确。
更新详细流程
管理端流程
客户端流程
客户端命令行
用法:
MagicUpdateWizard[/automation][/normal][/close:
hWnd[,Msg[,wParam[,lParam]]]][/background][/debug]
[/s:
[a][,ap1][,ap2][,ap3][,ae][,aep1][,aep2][,aep3][,fu][,fn][,fs][,fe][,ff][,fa][,hpa][hp1][,hp2][,hp3]]
[/noupdateself][/r:
exepath][/h/?
][/f[:
serchpath]]/mucpath
/automation-
自动执行更新,等同/s:
fu,ap1,aep1,hp1,ap2,hp2,aep2;
若没有更新会自动退出;
显示更新进度
/normal-正常模式,等同/s:
ap1,aep1,hp1;
隐藏页面1
/close:
hWnd-更新前发送关闭通知给窗口句柄hWnd(十进制);
Msg消息类型(十进制),默认WM_CLOSE;
wParam,lParam消息参数
/background-后台运行;
等同/s:
a,ae,hpa;
若有更新将自动升级,没有更新自动退出;
看不见窗口
/debug-
调试模式(包含/updatetest)
/updatetest-
更新服务器上的测试版本
/s:
-
显示类型
a
-自动执行;
,等同/s:
ap1,ap2,ap3;
但不会自动退出,有则更新
ap1
自动执行页面1
ap2
自动执行页面2
ap3
自动执行页面3
ae
自动退出,等同/s:
aep1,aep2,aep3;
aep1
自动退出页面1
aep2
自动退出页面2
aep3
自动退出页面3
fu-
有更新时,提示
fn-
没有更新时,提示
fs-
更新成功时,提示
fe-
更新失败时,提示
ff-
更新完成时提示时,提示;
fs,fe
fa-
提示全部;
fu,fn,ff
hpa-
隐藏所有页面;
hp1,hp2,hp3
hp1-
隐藏页面1
hp2-
隐藏页面2
hp3-
隐藏页面3
/noupdateself-
不进行自我更新
/r-
快退出时,执行exepath
/f-
自动搜索serchpath目录下的匹配的muc文件;
若省略,则搜索工作路径
mucpath-
muc文件路径
/h/?
显示本帮助
自我升级
大家知道,程序在运行时,不能改写和删除自己。
要改写自己最简单的方法就是创建一个新进程B,由新的进程B改写原来的进程A。
因此我按照如下的步骤实现自我更新。
新建一个空的Win32工程“EmbedUpdateSelf”。
在WinMain函数中添加更改原程序的代码,做好接口调用;
手动编辑原项目工程下的res\MagicUpdateWizard.rc2资源,以便在原程序中嵌入新的程序,在需要更新时,原程序从资源中读出数据并写到文件中。
添加如下代码:
#ifdef_DEBUG
IDR_EMBEDUPDATESELF
EmbedUpdateSelf
"
..\\..\\Bin\\EmbedUpdateSelfd.exe"
#else
..\\..\\Bin\\EmbedUpdateSelf.exe"
#endif
在更新服务器上放置需要更新的ZIP压缩包;
在A进程中判断是否需要更新,下载压缩包,启动进程B,由B进程解压缩ZIP,并负责A的更新;
5.
更新成功后,再次用A原来的命令行启动进程A;
6.
删除任何用的的临时文件。
小结
更新程序的大致原理粗糙的讲述完,篇幅所限在实际运用中还有很多的细节没有呈上,如更新程序和用户程序的通信(通知退出)、更新程序在实际使用的命令行方法、注意点、配置的服务器等。
写到这里还是意犹未尽。
试想我们是否可以实现像WindowUpdate一样,具有通知区域及服务程序的自动执行呢?
我们在下载过程中是否可以考虑P2P、迅雷、电驴技术,加快下载速度呢?
我们是否可以考虑在服务器上安装服务程序,进行必要的处理呢?
我们是否考虑过更新程序在其他平台(LINUX、苹果、PDA、塞班)上运行呢?
……
留给我们的疑问太多太多,可以升级的空间也太大太大,技术的拓展永无止境!
朋友们如果有什么好想法或更好的程序,欢迎来信(qmroom#
#=@)交流!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 桌面 软件 智能 更新 MagicUpdate 原理