许多程序都包含一个自动更新程序,程序偶尔会在线查找更新,然后下载并应用找到的任何更新。程序错误是固定的,支持文件被修改,事情(通常)变得更好。
不幸的是,无论我看起来多么努力,我无法在任何地方找到有关此过程的信息。似乎已经实施的自动更新程序要么是专有的,要么不被认为是重要的。
实现在网络上查找更新的系统并在可用时下载它们似乎相当容易。自动更新程序的那一部分将从实现到实现发生重大变化。问题是应用补丁的不同方法是什么。只需下载文件并用新文件替换旧文件,运行已下载的迁移脚本,猴子修补系统的部分等等?概念是首选,但Java,C,Python,Ruby,Lisp等中的示例将不胜感激。
答案 0 :(得分:47)
我认为“语言不可知”将成为限制因素。应用程序有如此多的形状和大小,没有一个通用的答案。我用几种语言实现了几个自动更新程序,没有两个是相似的。
最一般的理念是应用程序检查某些家庭位置(网址,网络查询,公司网络位置等),以询问其版本是否为最新版本,或询问最新版本是什么。如果答案要求更新,那么每个情况的处理都会有所不同。
一种流行的替代方法是在启动应用程序时邀请主位置运行脚本。该脚本可以检查版本,必要时下载更新,并询问使用反馈,例如。
如果缩小参数,我们可能会有所帮助。
更新:“修补”的方法也取决于应用程序的性质,这里有非常广泛的多样性。例如,如果您有一个可执行文件,那么替换可执行文件可能是最实际的。如果您的应用程序包含许多文件,您应该寻找最小化替换文件数量的方法。如果您的应用程序是高度自定义或参数化的,那么您应该尽量减少重新定制的工作量。如果您的应用程序使用解释代码(例如Excel VBA应用程序或MS Access MDB应用程序),那么您可以替换部分代码。在Java应用程序中,您可能只需要替换JAR文件,甚至替换JAR内容的子集。您还需要有一种方法来识别当前的客户端版本,并进行适当的更新。我可以继续下去,但我希望你能看到我对多样性的看法。这是很多次,当最佳答案通常以“嗯,这取决于......!”开头时。这就是为什么这么多答案包括“请缩小参数。”
答案 1 :(得分:18)
请务必考虑删除有关更新的信息以及更新二进制文件本身的安全隐患。
您相信下载的来源吗?您可以打电话回家进行更新,但如果中间有人重定向到恶意服务器怎么办? HTTPS或类似的安全连接会有所帮助,但建议使用数字签名检查双重检查最终下载的位。
答案 2 :(得分:8)
首先,您需要在应用程序主页上使用最新版本的文件。 我认为最好的方法是为此任务提供特殊的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)
答案 3 :(得分:5)
最简单的解决方案(由许多程序使用)运行先前版本的卸载程序并运行新安装程序的安装程序(可选择跳过用户已经回答的问题,如EULA)。唯一的问题是新版本必须能够从旧版本中读取配置选项。
此外,在Windows上,您无法删除正在使用的可执行文件,因此您可能希望在Temp文件夹中删除一个小的可执行文件,该文件夹运行整个过程,然后在最后从实例中删除它。已启动的新版本(或仅register it to be deleted at the next reboot)。
答案 4 :(得分:2)
最简单的方法是让您的程序查询服务器(网站)以查看是否有更新。如果有更新,您可以向用户显示一条消息,提示他们下载更新的版本并提供链接。
另一种更复杂的解决方案是创建一个小型Windows服务(或unix守护程序),定期检查是否有更新,此服务可以下载更新并启动安装程序。
一般的体系结构是您拥有一个可以控制的中央服务器,它知道最新版本以及从何处获取它。然后程序查询服务器。我不会包含示例代码,因为它在服务器和您选择的格式上是高度被告。但这并不困难。
答案 5 :(得分:2)
这不是一个完整的答案,而是我最近实施的自动更新机制的一个例子。这种情况与传统的Firefox类型的用户应用程序略有不同,因为它是工作中使用的内部工具。
基本上,它是一个小脚本,用于管理要在安装程序中构建和打包的Subversion分支队列。它读取一个小文件,其中写入分支的名称,获取第一个,在文件末尾重写它,并启动构建过程,这涉及调用一堆脚本。要构建的每个分支的配置都写在.INI文件中,与工具本身一起存储在Subversion存储库中。
因为这个工具在多台计算机上运行,所以我想在我对工具本身或配置脚本进行更改后,立即在所有计算机上自动更新它。
我实现它的方式很简单:当我启动工具时,它变成了“外壳”。这个外壳做了两件非常简单的事情:
svn update
本身和配置文件这个非常简单的更新 - 我自己在循环系统已经为我们服务了几个月。它非常优雅,因为它是独立的:自动更新程序是程序本身。因为“外壳”(自动更新程序部分)非常简单,所以它不会从更新中受益,因为“内壳”(每次都从更新的源文件执行)。
答案 6 :(得分:2)
有一件事没有真正提到过,您应该认真考虑运行程序的用户实际上可能没有足够的权限来升级它。这应该是非常常见的,至少对于商业用户而言,对于家庭用户来说可能更少。
出于安全原因,我总是使用(自我强加的)有限帐户,它总是让我感到愤怒,因为大多数自动更新程序只是假设我以管理员身份运行,然后在下载后失败并且不提供其他服务执行更新的方法,而不是实际关闭程序并在管理上下文中再次运行它。大多数人甚至不会缓存下载的更新,必须重新做一遍。
如果自动更新程序在需要时只是提示输入管理员凭据并继续使用它会好得多。
答案 7 :(得分:1)
由于自动更新是一种常见情况,因此大多数语言至少有一个可用于支持此功能的程序包。 (下面我列出了一些可用的软件包)
其中一个非常好的想法是.NET的ClickOnce发行版,它是一个安装程序,用于对您的应用程序进行沙盒化并安装在用户上下文中,因此无需管理员权限。您可以在发布中配置ClickOnce以检查每个应用程序启动的更新。
Java有Java Web Start,它为java applet提供了相同类型的功能。
Delphi有很多关于自动更新的文章,Torry有一个WebUpdate components列表,例如GoUpdater似乎有很多功能。
他们都使用网站/网络共享来检查新版本,而不是检索补丁或完整的安装文件并运行它。因此,您应该尝试为您的应用程序找到一个不错的软件包,以免您开发和维护自己的解决方案。
答案 8 :(得分:0)
在Java-Webstart设置中,您启动一个JNLP文件,然后触发下载运行该应用程序所需的Jar文件。每次webstart检查是否有更新版本的Jars,并将下载它们替换本地缓存的版本。使用名为jardiff的工具,您只会向较新的jar创建差异并通过服务器分发这些差异(例如,仅获取更新)。
优点:
缺点:
答案 9 :(得分:0)
阅读Carl Seleborgs的回答给了我一些关于通用代码库如何有用的想法。
svn附带了一个名为svnsync的工具,它的行为类似于svn导出,但跟踪导出的实际修订版本。
有人可以利用这个系统只从用户的实际版本中获取更改的文件。
实际上,您将拥有一个已编译二进制文件的存储库,并且运行svnsync将仅获取已修改的二进制文件。它还可以将本地更改与基于文本的配置文件合并到新的配置选项中。
答案 10 :(得分:0)
将补丁安装到程序的功能基本上是安装程序的基本功能之一。安装程序软件记录在很多地方,但通常基于每个安装程序:Microsoft Installer(带有Install Shield Extensions),Ruby gems,Java .jar文件,各种Linux软件包管理器系统( RPM,Apt-get)和其他人。
这些都是复杂的系统,它们解决了一般修补程序的问题,但对于略有不同的系统。要确定最适合您的方法,请考虑您的应用程序中最适合的系统中的哪一个。滚动你自己很好,但看看这些系统是一个开始的地方。
答案 11 :(得分:0)
您可以编写应用程序的内部模块来进行更新。您可以编写外部迷你应用程序来进行更新。
另请参阅.NET即时编译技术,它可以根据需要即时创建这样的迷你应用程序。例如,http://fly.sf.net/
答案 12 :(得分:0)
我将为Windows做出回答。
这种方式似乎运作良好。
在安装程序中执行:
1.创建一个作为LocalSystem运行的手动启动服务,启动时更新然后停止
2.更改服务权限,以便所有用户都可以启动该服务(如果所有用户都应该能够更新没有管理员权限)
3.使用简单机制启动时,更改主程序以检查更新。如果检测到更新,则提示用户是否要应用更新
4.如果用户接受更新,请启动该服务。
如果架构允许,请创建一种在更新运行时监控更新的方法。
答案 13 :(得分:0)
您可以使用我的解决方案(Target Eye项目的一部分)。 http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto
答案 14 :(得分:0)
如果您的软件是开源的,并且针对Linux或开发人员。将软件安装为git repo很有趣。并且让它偶尔或每次启动时拉动稳定分支。
当通过npm,sbt,mavan,stack,elm-package或类似方式管理您的应用程序时,这特别容易。
答案 15 :(得分:-1)
如果您要搜索跨平台软件更新解决方案,请查看www.updatenode.com
一些亮点:
试试吧。
顺便说一下,我是开源客户端开发团队的一员。 :)