许多程序包括自动更新程序,程序偶尔会在线查找更新,然后下载并应用找到的任何更新.程序错误是固定的,支持文件被修改,事情(通常)变得更好.
不幸的是,无论我看起来多么努力,我无法在任何地方找到有关此过程的信息.似乎已经实施的自动更新程序要么是专有的,要么不被认为是重要的.
实现在网络上查找更新的系统并在可用时下载它们似乎相当容易.自动更新程序的那一部分将从实现到实现发生重大变化.问题是应用补丁的不同方法是什么.只需下载文件并用新文件替换旧文件,运行已下载的迁移脚本,猴子修补系统的部分等等?概念是首选,但可以理解Java,C,Python,Ruby,Lisp等中的示例.
我认为"语言不可知"将成为限制因素.应用程序有如此多的形状和大小,没有一个通用的答案.我用几种语言实现了几个自动更新程序,没有两个是相似的.
最一般的理念是应用程序检查一些家庭位置(网址,网络查询,公司网络位置等),以询问它的版本是否是最新版本,或询问最新版本是什么.如果答案要求更新,则该过程对于每种情况都会有所不同.
一种流行的替代方案是在启动应用程序时邀请归属位置运行脚本.例如,该脚本可以检查版本,在必要时下载更新,并询问使用反馈.
如果缩小参数,我们可能会更好.
更新:"修补"的方法也取决于应用程序的性质,这里有非常广泛的多样性.例如,如果您有一个可执行文件,那么替换可执行文件可能是最实际的.如果您的应用程序包含许多文件,您应该寻找最小化替换文件数量的方法.如果您的应用程序是高度自定义或参数化的,那么您应该尽量减少重新定制的工作量.如果您的应用程序使用解释代码(例如Excel VBA应用程序或MS Access MDB应用程序),那么您可以替换部分代码.在Java应用程序中,您可能只需要替换JAR文件,甚至替换JAR内容的子集.您还需要有一种方法来识别当前的客户端版本,并进行适当的更新.我可以继续下去,但我希望你能看到我对多样性的看法.这是很多次,当最佳答案通常以"嗯,这取决于......!"开头时.这就是为什么这么多答案包括"请缩小参数".
请务必考虑删除有关更新的信息以及更新二进制文件本身的安全隐患.
你相信下载的来源吗?您可以打电话回家获取更新,但如果中间有人重定向到恶意服务器怎么办?HTTPS或类似的安全连接会有所帮助,但建议使用数字签名检查双重检查最终下载的位.
首先,您需要在应用程序主页上使用最新版本的文件.我认为最好的方法是为此任务提供特殊的SQL表,并在发布新版本/每晚构建完成后自动填充它.您的应用程序创建新线程,该线程请求带有版本的内置http链接并与当前进行比较.在.NET中,使用可以使用如下代码:
Version GetLatestVersion() { HttpWebRequestrequest = (HttpWebRequest)WebRequest.Create(new Uri(new Uri(http://example.net), "version.txt)); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (request.HaveResponse) { StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.Default); return new Version(stream.ReadLine()); } else { return null; } } Version latest = GetLatestVersion(); Version current = new Version(Application.ProductVersion); if (current < latest) { // you need an update } else { // you are up-to-date }
在这个例子中,version.php只有一个普通字符串,如1.0.1.0.
我可以提供的另一个提示 - 如何下载更新.我非常喜欢下一个想法:在你的应用程序的资源中有一串CLR代码,你可以动态编译(使用CodeDom)到一个临时文件夹,主应用程序调用它然后关闭.Updater读取参数,设置或注册表并下载新模块.并调用删除所有临时文件的主应用程序.完成!
(但这里的一切都是关于.NET)
最简单的解决方案(由许多程序使用)运行先前版本的卸载程序并运行新安装程序的安装程序(可选择跳过用户已经回答的问题,如EULA).唯一的问题是新版本必须能够从旧版本中读取配置选项.
此外,在Windows上,您无法删除正在使用的可执行文件,因此您可能希望在Temp文件夹中删除一个小的可执行文件,该文件夹运行整个过程,然后从新版本的实例中删除它它已启动(或只是注册它以在下次重新启动时删除).