我该如何实现自动更新程序?

问题描述 投票:62回答:16

许多程序包括自动更新程序,程序偶尔会在线查找更新,然后下载并应用找到的任何更新。程序错误是固定的,支持文件被修改,事情(通常)变得更好。

不幸的是,无论我看起来多么努力,我无法在任何地方找到有关此过程的信息。似乎已经实施的自动更新程序要么是专有的,要么不被认为是重要的。

实现在网络上查找更新的系统并在可用时下载它们似乎相当容易。自动更新程序的那一部分将从实现到实现发生重大变化。问题是应用补丁的不同方法是什么。只需下载文件并用新文件替换旧文件,运行已下载的迁移脚本,猴子修补系统的部分等等?概念是首选,但可以理解Java,C,Python,Ruby,Lisp等中的示例。

auto-update
16个回答
49
投票

我认为“语言不可知”将成为限制因素。应用程序有如此多的形状和大小,没有一个通用的答案。我用几种语言实现了几个自动更新程序,没有两个是相似的。

最一般的理念是应用程序检查一些家庭位置(网址,网络查询,公司网络位置等),以询问它的版本是否是最新版本,或询问最新版本是什么。如果答案要求更新,则该过程对于每种情况都会有所不同。

一种流行的替代方案是在启动应用程序时邀请归属位置运行脚本。例如,该脚本可以检查版本,在必要时下载更新,并询问使用反馈。

如果缩小参数,我们可能会更好。

更新:“修补”的方法也取决于应用程序的性质,这里有非常广泛的多样性。例如,如果您有一个可执行文件,那么替换可执行文件可能是最实际的。如果您的应用程序包含许多文件,您应该寻找最小化替换文件数量的方法。如果您的应用程序是高度自定义或参数化的,那么您应该尽量减少重新定制的工作量。如果您的应用程序使用解释代码(例如Excel VBA应用程序或MS Access MDB应用程序),那么您可以替换部分代码。在Java应用程序中,您可能只需要替换JAR文件,甚至替换JAR内容的子集。您还需要有一种方法来识别当前的客户端版本,并进行适当的更新。我可以继续下去,但我希望你能看到我对多样性的看法。这是很多次,当最佳答案通常以“嗯,这取决于......!”开头时。这就是为什么这么多答案包括“请缩小参数”。


0
投票

在Java-Webstart设置中,启动JNLP文件,然后触发下载运行应用程序所需的Jar文件。每次webstart检查是否有更新版本的Jars,并将下载它们替换本地缓存的版本。使用名为jardiff的工具,您将仅创建针对较新jar的差异并通过服务器分发这些差异(例如,仅获取更新)。

优点:

  • 总是最新的

缺点:

  • 你需要一个应用服务器(tomcat,JBoss)来分发文件
  • 你需要一个互联网连接才能获得申请

0
投票

阅读Carl Seleborgs的回答给了我一些关于通用代码库如何有用的想法。

svn附带了一个名为svnsync的工具,它的行为类似于svn导出,但跟踪导出的实际修订版本。

有人可以使用此系统,以便仅从用户实际修订中获取更改的文件。

实际上,您将拥有一个已编译二进制文件的存储库,并且运行svnsync将仅获取已修改的二进制文件。它还可以将本地更改与基于文本的配置文件合并到新的配置选项中。


0
投票

将补丁安装到程序的功能基本上是安装程序的基本功能之一。安装程序软件记录在很多地方,但通常基于每个安装程序:有Microsoft Installer(带有Install Shield Extensions),Ruby gemsJava .jar文件,各种Linux包管理器系统(RPMApt-get)等。

这些都是复杂的系统,它们解决了一般修补程序的问题,但对于略有不同的系统。要确定最适合您的方法,请考虑您的应用程序中最适合的系统中的哪一个。滚动你自己很好,但看这些系统是一个开始的地方。


0
投票

您可以编写应用程序的内部模块来进行更新。您可以编写外部迷你应用程序来进行更新。

另请参阅.NET即时编译技术,它可以根据需要即时创建这样的迷你应用程序。例如,http://fly.sf.net/


0
投票

0
投票

如果您的软件是开源的,并且针对Linux或开发人员。将您的软件安装为git repo很有趣。让它偶尔或每次启动时拉动稳定分支。

当您的应用程序通过npm,sbt,mavan,stack,elm-package等进行管理时,这一点非常简单。


-1
投票

如果您正在搜索跨平台软件更新解决方案,请查看www.updatenode.com

一些亮点:

  • 免费开源项目
  • 跨平台和开源更新客户端工具
  • 本地化已经为最重要的语言
  • 易于集成,易于操作
  • 基于云的管理平台,用于定义和管理更新
  • 为显示消息提供额外支持(通知新事件,产品等)
  • Web界面已打开(您可以使用该服务创建自己的客户端)
  • 许多使用情况统计信息,如使用的操作系统,地理位置,版本使用情况等。
  • 用于移动应用更新的Android API

就试一试吧。

顺便说一下,我是开源客户端开发团队的一员。 :)


18
投票

请务必考虑删除有关更新的信息以及更新二进制文件本身的安全隐患。

你相信下载的来源吗?您可以打电话回家进行更新,但如果中间有人重定向到恶意服务器怎么办? HTTPS或类似的安全连接会有所帮助,但建议使用数字签名检查双重检查最终下载的位。


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)


5
投票

最简单的解决方案(由许多程序使用)运行先前版本的卸载程序并运行新安装程序的安装程序(可选择跳过用户已经回答的问题,如EULA)。唯一的问题是新版本必须能够从旧版本中读取配置选项。

此外,在Windows上,您无法删除正在使用的可执行文件,因此您可能希望在Temp文件夹中删除一个小的可执行文件,该文件夹运行整个过程,然后从新版本的实例中删除它它被推出(或只是register it to be deleted at the next reboot)。


2
投票

最简单的方法是让您的程序查询服务器(网站)以查看是否有更新。如果有更新,您可以向用户显示一条消息,提示他们下载更新版本并提供链接。

另一种更复杂的解决方案是创建一个小型Windows服务(或unix守护程序),定期检查是否有更新,此服务可以下载更新并启动安装程序。

一般的体系结构是您拥有一个中央服务器,您可以控制它知道最新版本以及从何处获取它。然后程序查询服务器。我不会包含示例代码,因为它在服务器和您选择的格式上是高度被告。虽然这并不困难。


2
投票

这不是一个完整的答案,而是我最近实现的自动更新机制的一个例子。这种情况与传统的Firefox类型的用户应用程序略有不同,因为它是工作中使用的内部工具。

基本上,它是一个小脚本,管理要在安装程序中构建和打包的Subversion分支队列。它读取一个小文件,其中写入分支的名称,获取第一个,在文件末尾重写它,并启动构建过程,这涉及调用一堆脚本。要构建的每个分支的配置都写在.INI文件中,与工具本身一起存储在Subversion存储库中。

因为这个工具在几台计算机上运行,​​所以我想在我对工具本身或配置脚本进行更改后立即在所有计算机上自动更新它。

我实现它的方式很简单:当我启动工具时,它变成了“外壳”。这个外壳做了两件非常简单的事:

  • svn update本身和配置文件
  • 再次启动,这次是“内壳”,实际处理一个配置(然后再次退出)。

这个非常简单的更新 - 我自己在循环系统现在已经很好地服务了几个月。它非常优雅,因为它是独立的:自动更新程序是程序本身。因为“外壳”(自动更新程序部分)非常简单,所以它不会从更新中受益,因为“内壳”(每次都从更新的源文件执行)。


2
投票

有一件事没有真正提到过,你应该认真考虑运行程序的用户可能实际上没有足够的权限来升级它。这应该是非常常见的,至少对于商业用户来说,对于家庭用户来说可能更少。

出于安全原因,我总是使用(自我强加的)有限帐户,它总是让我感到愤怒,因为大多数自动更新程序只是假设我以管理员身份运行,然后在下载后失败并且不提供任何其他方式的执行除了实际关闭程序并在管理上下文中再次运行它之外的更新。大多数人甚至不缓存下载的更新,必须重新做一遍。

如果自动更新程序在需要时只是提示输入管理员凭据并继续使用它会好得多。


1
投票

由于自动更新是一种常见方案,因此大多数语言至少有一个可用于支持此功能的软件包。 (下面我列出了一些可用的包)

其中一个非常好的想法是.NET的ClickOnce发行版,它是一个安装程序,它将您的应用程序打包并安装在用户上下文中,因此不需要管理员权限。您可以在发布中配置ClickOnce以检查每个应用程序启动的更新。

Java有Java Web Start,它为java applet提供了相同的功能。

Delphi有很多关于自动更新的文章,Torry有一个WebUpdate components列表,例如GoUpdater似乎具有非常广泛的功能。

他们都使用网站/网络共享来检查新版本,而不是检索补丁或完整的安装文件并运行它。因此,您应该尝试为您的应用程序找到一个很好的软件包,以免您开发和维护自己的解决方案的麻烦。


1
投票

我将假设Windows的答案。

这种方式似乎运作良好。

在安装程序中执行: 1.创建一个作为LocalSystem运行的手动启动服务,在启动时,更新随后停止。 2.更改服务权限,以便所有用户都可以启动该服务(如果所有用户都应该能够更新没有管理员权限)。 3.使用简单机制启动时,更改主程序以检查更新。如果它检测到更新,则提示用户是否要应用更新。 4.如果用户接受更新,请启动该服务。

如果体系结构允许,请创建一种在运行时监视更新的方法。

© www.soinside.com 2019 - 2024. All rights reserved.