下面给出更新方案,该方案为WORD文档格式,文档下载地址点击进入下载
Windows程序自动升级设计方案
文件状态: [√] 草稿 [ ]正式发布 [ ] 正在修改 | 文件标识: | 升级设计方案 |
当前版本: | V0.5 | |
作 者: | 李吉磊 | |
完成日期: | 2018/08/31 |
2018年8月
修订记录
序号 | 版本号 | 修改日期 | 修改内容 | 修改人 | 批准人/日期 |
| V0.1 | 2018/08/27 | 创建文档 | 李吉磊 |
|
| V0.2 | 2018/08/28 | 修改流程图 | 李吉磊 |
|
| V0.3 | 2018/08/29 | 新增服务器流程图 | 李吉磊 |
|
| V0.4 | 2018/08/30 | 新增传输文件接口 | 李吉磊 |
|
| V0.5 | 2018/08/31 | 设计版本号 | 李吉磊 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
目录
为实现应用程序的自动升级更新,本文档给出了升级的流程结构设计及相应的客户端和服务器服务接口设计及相关信息配置,为参与流程设计的人员提供沟通和交流的基础。
-
- 适用范围
应用程序的自动升级
同组的流程及接口设计开发人员
术语和缩写 | 英文 | 描述 |
IPURL | Incremental package URL | 增量包下载地址 |
FPURL | Full amount of package URL | 全量包下载地址 |
|
|
|
参考文件 | 备注 |
|
|
由于在之前的探讨中发现使用管家主程序统一管理应用程序(将管家主程序一部分功能做为应用程序的更新程序,完成检测更新的目的)这一设计存在以下缺点:
- 由于使用管家程序,用户登录时需要首先登录管家程序,该步骤过于繁琐,可能不符合用户操作习惯。
- 管家程序设计的初衷是统一认证管理,管理多个同级权限的应用(由同一公司发布的多个应用)的更新,但在后续讨论中发现可能并不存在如此多的应用。
- 由于管家程序本身就是一个应用程序,需要考虑自身的更新升级,这无疑增加了用户操作的繁琐度,也增加了开发人员的工作量。
鉴于以上缺点,本文认为使用管家主程序实现升级更新这一设计的开发条件未充分满足,在应用过少,不改变用户使用习惯的前提下,给每个发布的应用程序配置相应的更新升级程序(可复用)成为本文的选择方案。
为实现程序自动更新的目的,需要为应用程序配备相应的更新程序。但由此也分歧出两种方案思路:
方案一、提供的桌面快捷方式实则指向该应用程序的更新程序,用户打开该图标后首先在后台运行更新程序,通过更新程序的检测结果反馈出应用程序是否需要更新,为何种更新并给出用户选项:1若无更新则打开应用程序提示用户登录2若存在更新则提示用户”立即更新”或”稍后更新”,该步骤结束后再打开应用程序。
方案二、提供的桌面快捷方式指向应用程序,用户打开该图标后首先打开应用程序,应用程序打开更新程序,通过更新程序的检测结果反馈出应用程序是否需要更新,为何种更新并给出用户选项:1若无更新则没有提示(更新程序直接退出),用户可以直接进行登录操作2若存在更新则提示用户”立即更新”或”稍后更新”,在更新过程中关闭应用程序,该步骤结束后再打开应用程序。
对比两种方案,各有优劣:
- 第一种方案占用较少步骤和系统资源,但存在更新程序在后台检测时间过长导致用户不明所以可能多次打开图标的问题。
- 第二种方案在应用程序不需要更新时极为方便快捷,可以直接进行登录操作,但若存在更新则需要关闭应用程序并再次打开,这占用较多系统资源。
总结两种方案的优劣,可以使用如下方法进行改进:
- 给第一种方案增加使用加载界面以给与用户提示。
- 第二种方案细化更新过程,将更新细分为兼容性更新(增加新的业务功能,增加接口,扩展接口内容等)和版本性更新(全盘重构,重大功能方向改变,增加大范围不兼容之前接口)并作出相应解决方案,提供后台更新功能,尽可能完善应用更新功能。
因确认版本号前三位为固用版本控制位,所以本设计着重设计第四位
例:v1.0.1.0831_s 和v1.5.0.0831_m
版本号第四位为确定版本的日期+该版本的更新等级
v1.0.1.0831_s:该版本号表示主版本为1,次版本为0,版本修订为1,确定版本的日期为8月31,该版本为建议(s)升级版本。
v1.5.0.0831_m:该版本号表示主版本为1,次版本为5,版本修订为0,确定版本的日期为8月31,该版本为强制(m)升级版本。
为实现软件更新的数据存储与读取,需要选择使用数据库或XML、JSON格式文件,本文选择XML文件以达到完善配置文件的需求。
为了XML文件的方便使用,本文选择第三方软件TINYXML2作为XML文档的解析工具。
方案一需要两个进程程序,一个是应用程序App.exe,一个是更新程序Update.exe。
方案二需要三个进程程序,一个是应用程序App.exe,一个是更新程序Update.exe,一个是后台更新程序BackGrand.exe。
-
-
-
- 对应流程说明
-
-
- 打开应用程序
- 应用程序打开更新程序
- 更新程序检测应用程序是否需要更新并反馈更新级别(兼容性(建议)更新(增加新的业务功能,增加接口,扩展接口内容等)和版本性(强制)更新(全盘重构,重大功能方向改变,增加大范围不兼容之前接口))
- 如要更新则下载更新文件
- 如是版本性更新则关闭应用程序,替换文件
- 如是兼容性更新则提示用户是否重启应用程序,若重启则替换文件,否则待本次应用程序结束后替换
- 更新配置信息
- 打开应用程序
- 关闭更新程序
-
-
- 更新流程图
-
-
-
-
-
- 子流程图
-
-
考虑到可能出现的跨版本升级情况,即可能很久没有用过该应用的用户打开应用时,如何设计更新?
本文给出设计是采用服务端增量包与全量包一起发布,根据用户当前的版本号区分下载更新是增量更新(增量包)还是全量更新(全量包)。
设计思路:在接收到用户当前版本后与历次更新版本号对比,若当前版本之上存在版本性强制更新则下载全量包,否则采用增量包。
由于上一套方案没有设计服务器的流程及相关配置文件,这里给出服务器的设计方案及思路。
服务器管理应用更新流程的版本对比、升级程度判断(区分版本性、兼容性)、下载URL路径及维护应用的更新日志。
服务器持有两份XML文件,一份XML文件(Newest.XML)为应用程序的最新配置信息,用于与客户端的应用信息相对比。一份XML(MainTain.XML)用于维护Newest.XML,服务器接口直接访问MainTain.XML以获取其维护的Newest.XML的信息,通过该信息获取应用最新配置信息。如此设计可保持服务器可不变动MainTain.XML文件地址及名字的情况下,快速读取Newest.XML文件的内容而不必知道它是否名字改变或位置改变(改动的部分必须写入MainTain.XML)。
本文使用Oracle数据库以维护应用的更新日志。
服务器中关于更新包的配置文件信息有:更新包版本号,更新包的增/全量下载URL,更新包的MD5校验码。
例:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<APPName>
<Ver>v1.2.0.0831_m</ver> //尾缀’m’表示强制更新版本,只有全量包URL
<FPURL>ftp://ljl:521125@192.168.6.174:21/</FPURL>
<MD5>4fa766df525d01c0a3e9210f8721e217</MD5>
</APPName>
<PackageName>
<Ver>v1.2.0.0831_s</ver> //尾缀’s’表示建议更新版本,有增/全量包URL
<IPURL>ftp://ljl:521125@192.168.6.174:21/</IPURL>
<FPURL>ftp://ljl:521125@192.168.6.174:21/</FPURL>
<MD5>4fa766df525d01c0a3e9210f8721e217</MD5>
</PackageName>
为实现软件更新的数据存储与读取,需要选择使用数据库或XML、JSON格式文件,本文选择XML文件和Oracle数据库相以达到完善配置文件及维护更新日志的需求。
为了XML文件的方便使用,本文选择第三方软件TINYXML2作为XML文档的解析工具。
为方便使用Oracle数据库,本文选择第三方应用PLSQL作为Oracle数据库的操作工具。
本方案需求:2份XML文件(Newest.XML、MainTain.XML),Oracle数据库表一张。
说明:
升级级别的判断为应用的当前版本与最新版本比较的结果
版本号格式:主版本+次版本+发布号+日期_此版本等级(m为强制,s为建议)
①当前版本与最新版本相同,则不需要更新
例:应用当前版本v1.0.0.0830_s,最新版本v1.0.0.0830_s,不需要更新
②当前版本与最新版本不同,且互为相邻版本,且最新版本为兼容性更新版本则判断为兼容性
例:应用当前版本v1.0.0.0830_s,最新版本v1.0.1.0830_s,兼容性更新
③当前版本与最新版本不同,且互为相邻版本,且最新版本为版本性更新版本则判断为版本性
例:应用当前版本v1.0.0.0830_s,最新版本v1.0.1.0831_m,版本性更新
④当前版本与最新版本不同,且其间存在间隔版本,且存在的间隔版本与最新版本皆为兼容性更新版本则判断为兼容性,此时增量包的个数为间隔版本个数+最新版本个数
例:应用当前版本v1.0.0.0830_s,间隔版本v1.0.1.830_s,v1.0.2.0830_s最新版本v1.0.3.0831_s,则增量包的个数为3
⑤当前版本与最新版本不同,且其间存在间隔版本,且存在的间隔版本或最新版本有一个为版本性更新版本则判断为版本性更新
例:应用当前版本v1.0.0.0830_s,间隔版本v1.0.1.830_s,v1.0.2.0830_s最新版本v1.1.0.0831_m,则全量包的个数为1,版本为v1.1.0.0831_m
例:应用当前版本v1.0.0.0830_s,间隔版本v1.0.1.830_m,v1.0.2.0830_s最新版本v1.1.0.0831_s,则全量包的个数为1,版本为v1.1.0.0831_s
UpdateWorkPort
-
-
-
- 接口描述
-
-
服务器处理应用程序的升级业务接口,包括不限于版本检查,跨版本判断,下载包类型判断,用户地址,用户信息。
说明:为兼容客户端两种升级方案,本接口提供更新标志和更新等级标志以方便客户端执行相应的功能。
-
-
-
- 接口请求
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
UserMac | String |
| Y | 用户的MAC地址 |
UserIp | String |
| Y | 用户的IP |
UserInfo | String |
| Y | 用户的配置信息,包括不限于电脑配置,更新时间 |
UserAppName | String |
| Y | 用户应用名字 |
UserVer | String |
| Y | 用户应用当前版本 例v1.0.0.0830_s |
ServerXMLName | String |
| Y | 服务器XML文件名 |
NewestVer | String |
| Y | 服务器应用最新版本 例v1.2.0.0831_m |
VerList | String |
| Y | 历次版本列表 |
UpdateMark | String |
| Y | 更新标志 1:需要更新 2:不需要更新 |
UpdateGrade | String |
| Y | 更新等级 1:版本性强制更新 2:兼容性建议更新 |
FileSize | String |
| Y | 文件大小 |
URLNum | String |
| Y | URL个数 |
IPURL | String |
| Y | 增量包下载地址 若存在多个增量包下载URL则每个URL之间用’|’分隔 例:ftp://ljl:521125@192.168.6.174:21/|ftp://***:****@192.168.6.174:21/ |
FPURL | String |
| Y | 全量包下载地址 |
PackageMD5 | String |
| Y | 下载包的MD5校验码 若存在多个下载包校验码,则每个MD5校验码之间用’|’分隔 例:4fa766df525d01c0a3e9210f8721e217|******************************** |
UpUserName | String |
| Y | 下载地址账号名 例:ljl |
UpUserPwd | String |
| Y | 下载地址账号密码 例:521125 |
UpIP | String |
| Y | 下载地址IP地址 例:192.168.6.174 |
UpPortNum | String |
| Y | 下载地址端口号 例:21 |
UpPath | String |
| Y | 下载相对路径 例:App_Data/ |
DBName | String |
| Y | 存储用户操作记录的数据库 |
ListName | String |
| Y | 存储用户操作记录的数据库中表名 |
接口报文范例
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<UpdateWorkPortRequest>
<UserMac></UserMac>
<UserIp></UserIp>
<UserInfo></UserInfo>
<UserAppName></UserAppName>
<UserVer></UserVer>
<ServerXMLName></ServerXMLName>
<NewestVer></NewestVer>
<VerList></VerList>
<UpdateMark></UpdateMark>
<UpdateGrade></UpdateGrade>
<FileSize></FileSize>
<URLNum></URLNum>
<IPURL></IPURL>
<FPURL></FPURL>
<PackageMD5></PackageMD5>
<UpUserName>
<UpUserPwd></UpUserPwd>
<UpIP></UpIP>
<UpPortNum></UpPortNum>
<UpPath></UpPath>
</UpUserName>
<DBName></DBName>
<ListName></ListName>
</UpdateWorkPortRequest>
-
-
-
- 接口应答
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
Code | string |
| Y | 接口调用状态, 0:升级接口调用成功。 1:升级接口调用失败。 2:数据库打开失败。 3:表打开失败。 4:XML打开失败。 |
Desc | string |
| N | 接口调用描述信息,当Code大于0时填写失败原因。 |
接口报文范例
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<UpdateWorkPortResponse>
<Code></Code>
<Desc></Desc>
</UpdateWorkPortResponse>
TransferFile
-
-
-
- 接口描述
-
-
当接收到客户端DownloadFile接口请求时,传输符合FileSize条件的文件。
-
-
-
- 接口请求
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
FileName | String |
| Y | 文件名字 |
PackageMD5 | String |
| Y | 文件包MD5校验码 |
AES | String |
| Y | AES加密密钥 |
MD5 | String |
| Y | MD5校验码 |
FileSize | String |
| Y | 文件大小 |
BeginFlag | String |
| Y | 文件开始下载标志 |
ConfirmBegin | String |
| Y | 确认开始标志 |
EndFlag | String |
| Y | 文件结束下载标志 |
ConfirmEnd | String |
| Y | 确认结束标志 |
-
-
-
- 接口应答
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
Code | String |
| Y | 接口调用状态, 0:文件传输接口调用成功。 1:文件传输接口调用失败。 |
Desc | string |
| N | 接口调用描述信息,当Code大于0时填写失败原因。 |
UpdateWorkPort
-
-
-
- 接口描述
-
-
客户端应用升级接口,通过获取本地应用版本信息等与服务器交互,反馈出应用的更新等级及更新判断。
-
-
-
- 接口请求
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
UserMac | String |
| Y | 用户的MAC地址 |
UserIp | String |
| Y | 用户的IP |
UserInfo | String |
| Y | 用户的配置信息,包括不限于电脑配置,更新时间 |
UserAppName | String |
| Y | 用户应用名字 |
UserVer | String |
| Y | 用户应用当前版本 例v1.0.0.0830_s |
接口报文范例
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<UpdateWorkPortRequest>
<UserMac></UserMac>
<UserIp></UserIp>
<UserInfo></UserInfo>
<UserAppName></UserAppName>
<UserVer></UserVer>
</AddLocalUserRequest>
-
-
-
- 接口应答
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
Code | String |
| Y | 接口调用状态, 0:升级接口调用成功。 1:升级接口调用失败。 |
UpdateMark | String |
| Y | 更新标志 1:需要更新 2:不需要更新 |
UpdateGrade | String |
| Y | 更新等级 1:版本性强制更新 2:兼容性建议更新 |
FileSize | String |
| Y | 文件大小 |
PackageMD5 | String |
| Y | 下载包的MD5校验码 若存在多个下载包校验码,则每个MD5校验码之间用’|’分隔 例:4fa766df525d01c0a3e9210f8721e217|******************************** |
URLNum | String |
| Y | URL个数 |
NewestVer | String |
| Y | 最新版本 例v1.2.0.0831_m |
DownLoadURL | String |
| Y | 更新文件的下载地址 若存在多个增量包下载URL则每个URL之间用’|’分隔 例:ftp://ljl:521125@192.168.6.174:21/|ftp://***:****@192.168.6.174:21/ |
UpUserName | String |
| Y | 下载地址账号名 例:ljl |
UpUserPwd | String |
| Y | 下载地址账号密码 例:521125 |
UpIP | String |
| Y | 下载地址IP地址 例:192.168.6.174 |
UpPortNum | String |
| Y | 下载地址端口号 例:21 |
UpPath | String |
| Y | 下载相对路径 例:App_Data/ |
Desc | String |
| N | 接口调用描述信息,当Code大于0时填写失败原因。 2:数据库打开失败。 3:表打开失败。 4:XML打开失败。 |
接口报文范例
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<UpdateWorkPortResponse>
<Code></Code>
<UpdateMark></UpdateMark>
<UpdateGrade></UpdateGrade>
<FileSize></FileSize>
<PackageMD5></PackageMD5>
<URLNum></URLNum>
<NewestVer></NewestVer>
<DownLoadURL></DownLoadURL>
<UpUserName>
<UpUserPwd></UpUserPwd>
<UpIP></UpIP>
<UpPortNum></UpPortNum>
<UpPath></UpPath>
</UpUserName>
<Desc></Desc>
</UpdateWorkPortResponse>
DownloadFile
-
-
-
- 接口描述
-
-
通过服务器接口返回的FileSize参数判断通过何种方式下载文件,若FileSize过大(G级别)则通过URL下载,反之通过本接口下载。
-
-
-
- 接口请求
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
BeginFlag | String |
| Y | 文件开始下载标志 |
ConfirmBegin | String |
| Y | 确认开始标志 |
Filename | String |
| Y | 下载文件的名字 |
PackageMD5 | String |
| Y | 文件包MD5校验码 |
FilePath | String |
| Y | 下载文件的路径 |
AES | String |
| Y | AES加密密钥 |
MD5 | String |
| Y | MD5校验码 |
FileSize | String |
| Y | 文件大小 |
EndFlag | String |
| Y | 文件结束下载标志 |
ConfirmEnd | String |
| Y | 确认结束标志 |
-
-
-
- 接口应答
-
-
参数名称 | 参数类型 | 参数长度 | 是否必须 | 描述 |
Code | String |
| Y | 接口调用状态, 0:文件下载接口调用成功。 1:文件下载接口调用失败。 |
TrueFlag | String |
| Y | 下载成功判断标志 1:下载失败 0:下载成功 |
Desc | string |
| N | 接口调用描述信息,当Code大于0时填写失败原因。 |
本设计中关于系统的错误设计:服务器执行升级流程时需打开XML和Oracle数据库,当这两个步骤任一出错时则升级终止。
考虑到客户端的更新业务,若服务器端读取XML失败则不能进行该业务,则升级终止,返回错误4:XML打开失败。
考虑到服务器与客户端更新同步,若服务器XML打开成功则可以进行升级判断但若此时服务器数据库或表打开失败,则升级终止,返回2:数据库打开失败或3:表打开失败。因为若是继续升级过程,则客户端是可以保证升级成功但服务器更新日志则不能保持同步更新!
当升级程序因为服务器原因被迫停止,则会向服务器再次申请升级,直到服务器正确受理或超过三次后显示检测升级失败。
错误编号 | 错误名称 | 错误原因 | 处理方式 |
2 |
| 服务器数据库打开失败 | 升级程序再次访问服务器 |
3 |
| 服务器表打开失败 | 升级程序再次访问服务器 |
4 |
| 服务器XML打开失败 | 升级程序再次访问服务器 |