应用程序自动升级解决方案 (.NET/非.NET都适用)

所以每次做了东西都会有话想说.

原来做 Pacgen (PAC file GENerator) 的时候, 为了实现自动升级, 专门写了个叫 Updative 的命令行工具 (当然还有个给程序用的 DLL), 会比对每一个文件的版本, 并且生成一个目录文件, 这样软件升级的时候就只需要下载更新的文件. 当时做得还是蛮有意思的. 可惜后来想做得更强大, 反倒把逻辑搞混了, 于是不了了之.

最近重写了 Pacgen, 并且因为不再使用 PAC 文件, 而是用 Privoxy 自带的 filter, 再叫 PACgen 也不大说得过去, 便改名 X-Wall, 也更直观. (欲知详情, 请访问 http://x-wall.org/)

所以怎么解决这个自动升级的问题呢? 网上其实有不少现成的类库, 不过我是个怕麻烦的人, 所以懒得去看文档… 我是使用的 Inno Setup 打包的程序. 所以一开始只是给程序提供了简单的版本检查, 下载新的安装包, 并且执行. 之后由用户手动完成. 因为安装包会记住用户之前的设置, 所以实际上这个过程除了多点几下下一步, 也没什么太大的不好.

所以整个流程便是, 启动安装包, 退出程序, 安装后再启动.

但说来我也知道 Inno Setup 有些命令很久了, 就是没联系到一起. 不过还好在有生之年这一天终于是出现了. 改动几行代码, 下载之后启动安装包时加上 /silent 开关, 便大功告成啦.

这里需要 Inno Setup 的相关配置文件添加上安装完成后启动的选项, 并且不能设置为在 silent 模式下禁用.

虽然这样一来, 每次更新都会更新全部文件, 但对于小工具来说, 文件大小还是非常能接受的. 加上我是把东西都放在 Github 上 (详情可以查看我的前一篇文章, 让 Github 成为免费的软件发布/下载/更新的服务器), 速度也不错.

让 Github 成为免费的软件发布/下载/更新的服务器

这年头, 自己动手丰衣足食, 不过真的做出来个什么好家伙, 要想分享给别人, 也得在网上找个地儿. 之前一直是拿博客的空间来放东西, 不过老实说 FTP 还真不够方便, 而且可能很多人还没有这么个空间, 囧.

后来知道有 Github 这个东西, 再后来发现 Github 有 raw (原始文件) 这个东西, 再后来发现 Github 还有 Github Pages 这个东西. 但 Github Pages 则是后话了.

raw 的路径是固定的, 并且非常规范, 同时有 SSL 加密. 比如 X-Wall 的安装文件我提供的下载地址就是 https://raw.github.com/vilic/x-wall/master/release/x-wall-setup.exe, 从前至后依次是 https://raw.github.com/用户/仓库/分支/目录. 人可以通过浏览器下载, 软件当然也可以通过 GET 拿到, 于是这里的下载和更新就解决啦.

顺便就提提 Visual Studio 提供的 ClickOnce 解决方案. ClickOnce 是个非常方便的东西, 特别是对于小工具来讲. 但也有很多局限性, 其中一些可以通过不那么优雅的方式解决 (比如自动启动, 因为如果直接把 exe 添加到启动目录, 是没法读到正确的设置文件的, 还有 Command Line 传递参数等问题), 另一些则比较… 比如每次升级之后, exe 文件的目录也变了 (其实相当于是新下载到了另一个文件夹), 防火墙/托盘图标之类的设置也就没了. 最近做的 X-Wall 也是因为这点最后放弃了 ClickOnce.

对于 ClickOnce 来说, 设置自动更新都是傻瓜化的, 这个蛮好, 所以图方便的话, 还是不错的选择. 而这里要说的是, 我们也可以将 ClickOnce 的应用部署到 Github 上. 不过多年前当作者第一次尝试这么做的时候, 结局是悲惨的. 因为 ClickOnce 有签名, 所以要保证提交的文件和签名是一致的. Git 默认安装提交的时候貌似会把 Windows 风格的换行变成 Linux 风格, 这个就是问题的原因了. 重新运行安装程序 (也许可以直接通过命令改, 但作者是懒人), 选择 “Commit as-is” 的选项.

之后, 把 ClickOnce 的应用发布到本地文件系统上, 也就是你的 Git 仓库所在的文件夹. 其实我们可以新建一个分支来专门放这些东西, 这个还是用 Github Pages 的时候学到的. 这个时候, ClickOnce 的自动更新设置中, 把地址设置成本地发布的这个文件夹提交到 Github 之后 raw 对应的目录即可. 最后提交代码, 大功告成.

最后再提一下 Github Pages. 当然你可以用来做个人/组织/项目的页面, 或许也可以用来做软件的下载/升级服务器. 之前说的 raw 上用户可以下载 exe 等等 binary 的文件, 软件也可以检查并下载更新, 唯有个缺点就是 MIME 类型有时候不那么尽如人意. 比如 js 也好, xml 也好, 都是 plain/text. 但用 Github Pages 理论上来讲就可以避免这个情况了. 总体来说, 如果你不嫌麻烦那么一点点, 并且不需要 SSL 加密连接的话, 用 Github Pages 做这个事情或许会更好.

另外 X-Wall 的主页也是架设在 Github 上的, 欢迎访问! http://x-wall.org/