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

时间:2022-09-20 11:13:11

Many programs include an auto-updater, where the program occasionally looks online for updates, and then downloads and applies any updates that are found. Program bugs are fixed, supporting files are modified, and things are (usually) made better.

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

Unfortunately no matter how hard I look, I can't find information on this process anywhere. It seems like the auto-updaters that have been implemented have either been proprietary or not considered important.

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

It seems fairly easy to implement the system that looks for updates on a network and downloads them if they are available. That part of the auto-updater will change significantly from implementation to implementation. The question is what are the different approaches of applying patches. Just downloading files and replacing old ones with new ones, running a migration script that was downloaded, monkey patching parts of the system, etc.? Concepts are preferred, but examples in Java, C, Python, Ruby, Lisp, etc. would be appreciated.

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

16 个解决方案

#1


46  

I think that "language agnostic" is going to be a limiting factor here. Applications come in so many shapes and sizes that there is no one-size-fits-all answer. I have implemented several auto-updaters in several languages, and no two were similar.

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

The most general philosophy is that the application checks with some home location (web address, web query, corporate network location, etc.) to either ask if it's version is current, or ask what the most current version is. If the answer calls for an update, that process will be different for each situation.

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

A popular alternative is to invite the home location to run a script when the application is initiated. The script can check the version, download updates if necessary, and ask for usage feedback, for example.

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

We can probably help better if you narrow the parameters.

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

UPDATE: The approach to "patching" also depends on the nature of the application, and there's a very wide diversity here. If you have a single executable file, for instance, then it's probably most practical to replace the executable. If your application has many files, you should look for ways to minimize the number of files replaced. If your application is highly customized or parameterized, you should strive to minimize the re-tailoring effort. If your application employs interpreted code (such as an Excel VBA application or MS Access MDB application), then you may be able to replace parts of the code. In a Java application you may only need to replace a JAR file, or even a subset of the JAR contents. You'll also need to have a way to recognize the current client version, and update it appropriately. I could go on and on, but I hope you see my point about diversity. This is one of those many times when the best answer usually starts with "Well, it depends ...!" That's why so many answers include "Please narrow the parameters."

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

#2


18  

Be sure to also consider the security implications of sucking down information about the update, as well as the update binaries themselves.

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

Do you trust the source of the download? You maybe phoning home to got your update, but what if there is a man in the middle who redirects to a malicious server. An HTTPS or similar secure connection will help, but double checking the bits that you eventually download by using a digital signature check is recommended.

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

#3


8  

First you need a file on your application home web site with the latest version. The best way I think to have special SQL table for this task and populate it automatically after publishing new version / nightly build completion. Your application creates new thread which requests built-in http link with version and compares in with current. In .NET use can use code like this:

首先,您需要在应用程序主页上使用最新版本的文件。我认为最好的方法是为此任务提供特殊的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
}

In this example, version.php in only one plain string like 1.0.1.0.

在这个例子中,version.php只有一个普通字符串,如1.0.1.0。

Another tip I can give - how to download an update. I like very much next idea: in the resources of your application there is a string of CLR-code which you compile on-the-fly (using CodeDom) to a temporary folder, main application calls it and goes to close. Updater reads arguments, settings or registry and downloads new modules. And calls main application which deletes all temporary files. Done!

我可以提供的另一个提示 - 如何下载更新。我非常喜欢下一个想法:在你的应用程序的资源中有一串CLR代码,你可以动态编译(使用CodeDom)到一个临时文件夹,主应用程序调用它然后关闭。 Updater读取参数,设置或注册表并下载新模块。并调用删除所有临时文件的主应用程序。完成!

(But everything here is about .NET)

(但这里的一切都是关于.NET的)

#4


5  

The simplest solutions (used by many programs) is running the uninstaller for the previous version and the running the installer for the new one (optionally skipping questions which the user has already answered, like the EULA). The only catch is that the new version must be able to read the configuration options from the old version.

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

Also, on Windows you can't delete an executable file which is in use, so you probably will want to drop a small executable in Temp folder, which runs the whole process and then delete it at the end from the instance of the new version which got launched (or just register it to be deleted at the next reboot).

此外,在Windows上,您无法删除正在使用的可执行文件,因此您可能希望在Temp文件夹中删除一个小的可执行文件,该文件夹运行整个过程,然后从新版本的实例中删除它它已启动(或只是注册它以在下次重新启动时删除)。

#5


2  

The simplest approach would be to have your program query a server (website) to see if there is an update. If there is an update you could display a message to the user that prompts them to download a newer version and provides a link.

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

An alternative and more complex solution would be to create a small windows service (or unix daemon) that checks periodically to see if there are updates, this service can download the update and launch the installer.

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

The general architecture is that you have a central server that you control that knows the latest version and where to get it. Then the programs query the server. I am not going to include sample code because it is highly defendant on the server and the format you choose. It is not terrible difficult though.

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

#6


2  

This is not so much a complete answer, but rather one example of auto-updating mechanism I implemented recently. The situation is a little different from the tradition Firefox-type of user application, since it was an internal tool used at work.

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

Basically, it's a little script that manages a queue of Subversion branches to be built and packaged in an installer. It reads a little file, where the names of the branches are written, takes the first one, re-writes it at the end of the file, and launches the build process, which involves calling a bunch of scripts. The configuration for each branch to build is written in a .INI file, stored in a Subversion repository along with the tool itself.

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

Because this tool runs on several computers, I wanted a way to update it automatically on all machines as soon as I made a change either to the tool itself, or to the configuration scripts.

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

The way I implemented it was simple: when I launch the tool, it becomes an "outer shell". This outer shell does 2 very simple things:

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

  • svn update on itself and on the configuration files
  • svn更新自身和配置文件

  • launch itself again, this time as the "inner shell", the one that actually handles one configuration (and then exits again).
  • 再次启动自己,这次作为“内壳”,实际处理一个配置(然后再次退出)。

This very simple update-myself-in-a-loop system has served us very well for a few months now. It's very elegant, because it is self-contained: the auto-updater is the program itself. Because "outer shell" (the auto-updater part) is so simple, it doesn't matter that it does not benefit from the updates as the "inner shell" (which gets executed from the updated source file every time).

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

#7


2  

One thing that hasn't really been mentioned is that you should seriously consider that the user running your program might not actually have sufficient privileges to upgrade it. This should be pretty common at least for business users, probably less so for home users.

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

I'm always working with a (self-imposed) limited account for security reasons and it always pisses me off that most auto-updaters simply assume that I'm running as admin and then after downloading just fail and offer no other way of performing the update other than actually closing the program and running it again in an administrative context. Most do not even cache the downloaded update and have to do it all over again.

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

It'd be much better if the auto-updater would simply prompt for admin credentials when needed and get on with it.

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

#8


1  

Because auto updating is a common scenario, most languages have at least one package available to support this. (Below I list some of the available packages)

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

One of the really nice idea's is the ClickOnce distribution for .NET, it's an installer which sandboxes your application and installs in the user context, so no administrator rights required. You can configure the ClickOnce in your publish to check for updates each application start.

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

Java has Java Web Start which offers the same kind of functionality for java applets.

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

Delphi has numerous articles about auto-updating, Torry has a list of WebUpdate components, for instance GoUpdater seems to have a very wide range of functionality.

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

They all use a website/network share to check for a new version and than retrieve either a patch or a complete install file and run it. So you should try to find a nice package for your application, to save you the hassle of developing and maintaining your own solution.

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

#9


0  

In a Java-Webstart setting you start a JNLP file which then triggers the download of the Jar files needed to run the application. Everytime webstart checks if there are newer versions of the Jars and would download them replacing the locally cached ones. With a tool named jardiff you will create only diffs towards the newer jars and distribute these via the server (e.g. only get an update).

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

Pros:

  • always up to date
  • 总是最新的

Cons:

  • you need an application server (tomcat, JBoss) in order to distribute the files
  • 你需要一个应用服务器(tomcat,JBoss)来分发文件

  • you need an internet connection in order to get the application
  • 你需要一个互联网连接才能获得申请

#10


0  

Reading Carl Seleborgs answer gave me some ideas how a generic code-repository could be useful.

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

svn comes with a tool called svnsync, which sort of behaves like an svn export but keeps track of the actual revision your export is at.

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

Someone could utilize this system in order to only fetch the changed files from the users actual revision.

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

In actuality, you will have a repository with the binaries compiled, and running svnsync will only fetch the binaries that has been modified. It might also be able to merge local changes to text-based configuration files with new configuration-options.

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

#11


0  

The function of installing a patch to a program is basically one of the basic functions of an installer. Installer software is documented in numerous places but usually on a per-installer basis: There the Microsoft Installer (with Install Shield Extensions), Ruby gems, Java .jar files, the various Linux package manager systems (RPM, Apt-get)and others.

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

These are all complex systems which solve the problem of patching program in general but for slightly different systems. To decide what is best for you, consider which of these system your application most resembles. Rolling your own is fine but looking at these systems is a place to start.

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

#12


0  

You can write an internal module of your application to do updates. You can write an external mini application to do updates.

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

Also look at .NET on-the-fly compilation technology, it makes possible to create such mini application on-the-fly on demand. For example, http://fly.sf.net/

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

#13


0  

I'm going to assume answer for Windows.

我将假设Windows的答案。

This way seems to work well.

这种方式似乎运作良好。

In the installer do:
1. Create a manual-start service that runs as LocalSystem that when started does the update then stops.
2. Change the service permissions so all users can start the service (if all users should be able to update w/o admin rights).
3. Change the main program to check for updates when started using a simple mechanism. If it detects an update, prompt if the user wants to apply it.
4. If user accepts the update, start the service.

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

If the architecture allows for it, create a way to monitor the update as it is running.

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

#14


0  

You can use my solution (part of the Target Eye project). http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto

您可以使用我的解决方案(Target Eye项目的一部分)。 http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto

#15


0  

If your software is open sourced, and target Linux or developers. It is interesting to install your software as a git repo. And having it pull the stable branch occasionally or everytime when it is launched.

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

This is particular easy when your application is managed via npm, sbt, mavan, stack, elm-package or alike.

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

#16


-1  

If you are searching for an cross-platform software update solution, take a look at www.updatenode.com

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

Some highlights:

  • free for Open Source projects
  • 免费开源项目

  • cross-platform & Open Source update client tool
  • 跨平台和开源更新客户端工具

  • localized already for the most important languages
  • 本地化已经为最重要的语言

  • easy to integrate and easy to handle
  • 易于集成且易于操作

  • cloud based management platform to define and manage updates
  • 基于云的管理平台,用于定义和管理更新

  • provides additionally support for displaying messages (inform about new events, products, etc.)
  • 为显示消息提供额外支持(通知新事件,产品等)

  • web interface is open (you can create your own client using the service)
  • Web界面已打开(您可以使用该服务创建自己的客户端)

  • many usage statistics, as used operating systems, geo location, version usage, etc.
  • 许多使用情况统计信息,如使用的操作系统,地理位置,版本使用情况等。

  • Android API for mobile App updates
  • 用于移动应用更新的Android API

Just try it.

就试一试吧。

BTW, I am part of the dev team for the open source client. :)

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

#1


46  

I think that "language agnostic" is going to be a limiting factor here. Applications come in so many shapes and sizes that there is no one-size-fits-all answer. I have implemented several auto-updaters in several languages, and no two were similar.

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

The most general philosophy is that the application checks with some home location (web address, web query, corporate network location, etc.) to either ask if it's version is current, or ask what the most current version is. If the answer calls for an update, that process will be different for each situation.

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

A popular alternative is to invite the home location to run a script when the application is initiated. The script can check the version, download updates if necessary, and ask for usage feedback, for example.

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

We can probably help better if you narrow the parameters.

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

UPDATE: The approach to "patching" also depends on the nature of the application, and there's a very wide diversity here. If you have a single executable file, for instance, then it's probably most practical to replace the executable. If your application has many files, you should look for ways to minimize the number of files replaced. If your application is highly customized or parameterized, you should strive to minimize the re-tailoring effort. If your application employs interpreted code (such as an Excel VBA application or MS Access MDB application), then you may be able to replace parts of the code. In a Java application you may only need to replace a JAR file, or even a subset of the JAR contents. You'll also need to have a way to recognize the current client version, and update it appropriately. I could go on and on, but I hope you see my point about diversity. This is one of those many times when the best answer usually starts with "Well, it depends ...!" That's why so many answers include "Please narrow the parameters."

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

#2


18  

Be sure to also consider the security implications of sucking down information about the update, as well as the update binaries themselves.

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

Do you trust the source of the download? You maybe phoning home to got your update, but what if there is a man in the middle who redirects to a malicious server. An HTTPS or similar secure connection will help, but double checking the bits that you eventually download by using a digital signature check is recommended.

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

#3


8  

First you need a file on your application home web site with the latest version. The best way I think to have special SQL table for this task and populate it automatically after publishing new version / nightly build completion. Your application creates new thread which requests built-in http link with version and compares in with current. In .NET use can use code like this:

首先,您需要在应用程序主页上使用最新版本的文件。我认为最好的方法是为此任务提供特殊的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
}

In this example, version.php in only one plain string like 1.0.1.0.

在这个例子中,version.php只有一个普通字符串,如1.0.1.0。

Another tip I can give - how to download an update. I like very much next idea: in the resources of your application there is a string of CLR-code which you compile on-the-fly (using CodeDom) to a temporary folder, main application calls it and goes to close. Updater reads arguments, settings or registry and downloads new modules. And calls main application which deletes all temporary files. Done!

我可以提供的另一个提示 - 如何下载更新。我非常喜欢下一个想法:在你的应用程序的资源中有一串CLR代码,你可以动态编译(使用CodeDom)到一个临时文件夹,主应用程序调用它然后关闭。 Updater读取参数,设置或注册表并下载新模块。并调用删除所有临时文件的主应用程序。完成!

(But everything here is about .NET)

(但这里的一切都是关于.NET的)

#4


5  

The simplest solutions (used by many programs) is running the uninstaller for the previous version and the running the installer for the new one (optionally skipping questions which the user has already answered, like the EULA). The only catch is that the new version must be able to read the configuration options from the old version.

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

Also, on Windows you can't delete an executable file which is in use, so you probably will want to drop a small executable in Temp folder, which runs the whole process and then delete it at the end from the instance of the new version which got launched (or just register it to be deleted at the next reboot).

此外,在Windows上,您无法删除正在使用的可执行文件,因此您可能希望在Temp文件夹中删除一个小的可执行文件,该文件夹运行整个过程,然后从新版本的实例中删除它它已启动(或只是注册它以在下次重新启动时删除)。

#5


2  

The simplest approach would be to have your program query a server (website) to see if there is an update. If there is an update you could display a message to the user that prompts them to download a newer version and provides a link.

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

An alternative and more complex solution would be to create a small windows service (or unix daemon) that checks periodically to see if there are updates, this service can download the update and launch the installer.

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

The general architecture is that you have a central server that you control that knows the latest version and where to get it. Then the programs query the server. I am not going to include sample code because it is highly defendant on the server and the format you choose. It is not terrible difficult though.

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

#6


2  

This is not so much a complete answer, but rather one example of auto-updating mechanism I implemented recently. The situation is a little different from the tradition Firefox-type of user application, since it was an internal tool used at work.

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

Basically, it's a little script that manages a queue of Subversion branches to be built and packaged in an installer. It reads a little file, where the names of the branches are written, takes the first one, re-writes it at the end of the file, and launches the build process, which involves calling a bunch of scripts. The configuration for each branch to build is written in a .INI file, stored in a Subversion repository along with the tool itself.

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

Because this tool runs on several computers, I wanted a way to update it automatically on all machines as soon as I made a change either to the tool itself, or to the configuration scripts.

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

The way I implemented it was simple: when I launch the tool, it becomes an "outer shell". This outer shell does 2 very simple things:

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

  • svn update on itself and on the configuration files
  • svn更新自身和配置文件

  • launch itself again, this time as the "inner shell", the one that actually handles one configuration (and then exits again).
  • 再次启动自己,这次作为“内壳”,实际处理一个配置(然后再次退出)。

This very simple update-myself-in-a-loop system has served us very well for a few months now. It's very elegant, because it is self-contained: the auto-updater is the program itself. Because "outer shell" (the auto-updater part) is so simple, it doesn't matter that it does not benefit from the updates as the "inner shell" (which gets executed from the updated source file every time).

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

#7


2  

One thing that hasn't really been mentioned is that you should seriously consider that the user running your program might not actually have sufficient privileges to upgrade it. This should be pretty common at least for business users, probably less so for home users.

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

I'm always working with a (self-imposed) limited account for security reasons and it always pisses me off that most auto-updaters simply assume that I'm running as admin and then after downloading just fail and offer no other way of performing the update other than actually closing the program and running it again in an administrative context. Most do not even cache the downloaded update and have to do it all over again.

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

It'd be much better if the auto-updater would simply prompt for admin credentials when needed and get on with it.

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

#8


1  

Because auto updating is a common scenario, most languages have at least one package available to support this. (Below I list some of the available packages)

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

One of the really nice idea's is the ClickOnce distribution for .NET, it's an installer which sandboxes your application and installs in the user context, so no administrator rights required. You can configure the ClickOnce in your publish to check for updates each application start.

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

Java has Java Web Start which offers the same kind of functionality for java applets.

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

Delphi has numerous articles about auto-updating, Torry has a list of WebUpdate components, for instance GoUpdater seems to have a very wide range of functionality.

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

They all use a website/network share to check for a new version and than retrieve either a patch or a complete install file and run it. So you should try to find a nice package for your application, to save you the hassle of developing and maintaining your own solution.

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

#9


0  

In a Java-Webstart setting you start a JNLP file which then triggers the download of the Jar files needed to run the application. Everytime webstart checks if there are newer versions of the Jars and would download them replacing the locally cached ones. With a tool named jardiff you will create only diffs towards the newer jars and distribute these via the server (e.g. only get an update).

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

Pros:

  • always up to date
  • 总是最新的

Cons:

  • you need an application server (tomcat, JBoss) in order to distribute the files
  • 你需要一个应用服务器(tomcat,JBoss)来分发文件

  • you need an internet connection in order to get the application
  • 你需要一个互联网连接才能获得申请

#10


0  

Reading Carl Seleborgs answer gave me some ideas how a generic code-repository could be useful.

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

svn comes with a tool called svnsync, which sort of behaves like an svn export but keeps track of the actual revision your export is at.

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

Someone could utilize this system in order to only fetch the changed files from the users actual revision.

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

In actuality, you will have a repository with the binaries compiled, and running svnsync will only fetch the binaries that has been modified. It might also be able to merge local changes to text-based configuration files with new configuration-options.

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

#11


0  

The function of installing a patch to a program is basically one of the basic functions of an installer. Installer software is documented in numerous places but usually on a per-installer basis: There the Microsoft Installer (with Install Shield Extensions), Ruby gems, Java .jar files, the various Linux package manager systems (RPM, Apt-get)and others.

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

These are all complex systems which solve the problem of patching program in general but for slightly different systems. To decide what is best for you, consider which of these system your application most resembles. Rolling your own is fine but looking at these systems is a place to start.

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

#12


0  

You can write an internal module of your application to do updates. You can write an external mini application to do updates.

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

Also look at .NET on-the-fly compilation technology, it makes possible to create such mini application on-the-fly on demand. For example, http://fly.sf.net/

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

#13


0  

I'm going to assume answer for Windows.

我将假设Windows的答案。

This way seems to work well.

这种方式似乎运作良好。

In the installer do:
1. Create a manual-start service that runs as LocalSystem that when started does the update then stops.
2. Change the service permissions so all users can start the service (if all users should be able to update w/o admin rights).
3. Change the main program to check for updates when started using a simple mechanism. If it detects an update, prompt if the user wants to apply it.
4. If user accepts the update, start the service.

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

If the architecture allows for it, create a way to monitor the update as it is running.

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

#14


0  

You can use my solution (part of the Target Eye project). http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto

您可以使用我的解决方案(Target Eye项目的一部分)。 http://www.codeproject.com/Articles/310530/Target-Eye-Revealed-part-Target-Eyes-Unique-Auto

#15


0  

If your software is open sourced, and target Linux or developers. It is interesting to install your software as a git repo. And having it pull the stable branch occasionally or everytime when it is launched.

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

This is particular easy when your application is managed via npm, sbt, mavan, stack, elm-package or alike.

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

#16


-1  

If you are searching for an cross-platform software update solution, take a look at www.updatenode.com

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

Some highlights:

  • free for Open Source projects
  • 免费开源项目

  • cross-platform & Open Source update client tool
  • 跨平台和开源更新客户端工具

  • localized already for the most important languages
  • 本地化已经为最重要的语言

  • easy to integrate and easy to handle
  • 易于集成且易于操作

  • cloud based management platform to define and manage updates
  • 基于云的管理平台,用于定义和管理更新

  • provides additionally support for displaying messages (inform about new events, products, etc.)
  • 为显示消息提供额外支持(通知新事件,产品等)

  • web interface is open (you can create your own client using the service)
  • Web界面已打开(您可以使用该服务创建自己的客户端)

  • many usage statistics, as used operating systems, geo location, version usage, etc.
  • 许多使用情况统计信息,如使用的操作系统,地理位置,版本使用情况等。

  • Android API for mobile App updates
  • 用于移动应用更新的Android API

Just try it.

就试一试吧。

BTW, I am part of the dev team for the open source client. :)

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