本文将讨论一种桌面程序自动更新方案,其步骤比较多,但原理非常简单,通用性尚可。如果你有更完美的解决方案,欢迎留言探讨。

获取新版本程序

  1. 获取服务器上的的应用程序信息(最好有一个应用程序唯一ID);
  2. 服务器返回应用程序ID、应用程序英文名、应用程序中文名、应用程序描述、应用程序版本号、更新包文件名、发布时间、HTTP下载链接(url)、Zip更新包(程序只有一个可执行时可以不用安装包)的MD5或SHA1等信息
  3. 判断当前应用程序版本是否小于服务器上的版本(谨慎起见最好不要判断不等于),如果小于服务器上的版本则下载新版本的应用程序;
  4. 下载Zip包(非安装包,安装包无法做到静默升级)或新版本的应用程序。

直接部署

Windows系统下可以重命名/移动正在运行的文件和它依赖的动态链接库,但是不能删除。Linux系统下可以删除正在运行的程序。

如果应用程序只有一个可执行文件,更新操作会简单一点。假设可执行文件名为app.exeLinux系统下的部署过程如下:

  • 下载 update.exe
  • 删除正在运行的 app.exe
  • update.exe 重命名为 app.exe
  • 重新启动应用程序

Windows系统下部署过程如下:

  • 下载 update.exe
  • 将正在运行的 app.exe 重命名为app.exe.old
  • update.exe 重命名为 app.exe
  • 重启应用程序后删除 app.exe.old

解压部署

如果程序中包含多个文件,则需要将应用程序及其依赖放到压缩包中,这样更新操作会复杂一点,以下是Windows版本的的解压部署过程(Linux版本可以在部署成功后将旧文件直接删除)。

方法1 - 将旧版本程序改名:

  • 将Zip更新包(假如文件名为myapp_1.2.4.zip)下载到temp文件夹中;
  • 可以使用XZip/XUnzip解压缩,遍历temp/myapp_1.2.4.zip包中的文件;
  • 如果更新包中的文件在安装目录下不存在,则直接保存;
  • 如果更新包中的文件在安装目录下已存在,则先将原来的文件重命名为*.dll.old (也可以考虑改名后将文件设为隐藏属性),再将包中的*.dll 文件保存。
  • 全部更新完成后重启程序,将安装目录(及其子文件夹)下后缀名为*.old的文件(夹)删除。

方法2 - 移动旧版本程序:

  • 将Zip更新包(假如文件名为myapp_1.2.4.zip)下载到temp文件夹中;
  • 可以使用XZip/XUnzip解压缩,遍历temp/myapp_1.2.4.zip包中的文件;
  • 将安装目录中和更新包中同时存在的旧版本文件移动到一个临时文件夹下,例如以旧版本号命名2.3.12 (有点绕,其实移动的是旧版本的文件);
  • 将更新包中的文件保存到安装目录中(因为这个时候不存在同名文件了,可以直接保存)。
  • 全部更新完成后重启程序,删除2.3.12 目录(及其子文件夹)下的所有文件(夹)。

注意要跳过程序的配置文件及数据文件,不要造成配置文件和数据文件的丢失。可以在包中添加配置文件,设置指定的文件是否要强制更新。

这种两种方法的缺点是:解压过程中不能中断操作,这时候新版本程序还没有部署完成,旧版本的程序已被改名/移动,中断部署可能造成程序无法执行。

使用配置文件

如果程序是压缩包,可以为应用程序、及其所依赖的动态库、数据库文件等都设定一个版本号,每个文件的版本号都记录在一个 XML 文件中。解压时,对比更新包中的文件的版本号及当前安装的文件的版本号,根据情况进行相应的操作。这样既可以保证配置文件及数据文件不能被进行强制覆盖,也可以在相应的时候对数据文件的更新操作,更可以避免重新部署某些没有改变过文件。

下面是有道词典的版本文件格式,供大家参考:

<?xml version="1.0" encoding="UTF-8"?>
<versions>
    <main>880</main>
    <modules>
        ......
        <module><name>res</name><ver>610</ver></module>
        <module><name>resultui</name><ver>830</ver></module>
        <module><name>YodaoDict.api</name><ver>30</ver></module>
        <module><name>InstallDaemon.exe</name><ver>70</ver></module>
        <module><name>YoudaoDictInstaller.exe</name><ver>880</ver></module>
        <module><name>uninst.exe</name><ver>880</ver></module>
        <module><name>text_extractor_host_manifest.json</name><ver>10</ver></module>
        ......
    </modules>
</versions>

总结

Windows系统下提供ClickOnce部署技术,不过要求的条件过多而且不太好用,例如会自动安装.Net Framework等。理论上Linux系统下也可以使用上面介绍的方法自动更新应用程序,但是实际使用中由于各种各样的操作系统和不同情况,可能需要通过make install安装程序(或依赖的包),这种方法也不太理想。

标签: 部署, 自动更新

仅有一条评论

  1. […] 本文将在上一篇文章应用程序自动更新解决方案的基础上讨论一种新型的应用程序自动更新解决方案。 […]

添加新评论