Wie soll ich einen Auto-Updater implementieren?


71

Viele Programme enthalten einen automatischen Updater, bei dem das Programm gelegentlich online nach Updates sucht und dann alle gefundenen Updates herunterlädt und anwendet. Programmfehler werden behoben, unterstützende Dateien werden geändert und die Dinge werden (normalerweise) verbessert.

Leider kann ich nirgendwo Informationen über diesen Prozess finden, egal wie genau ich hinschaue. Es scheint, dass die implementierten Auto-Updater entweder proprietär waren oder nicht als wichtig angesehen wurden.

Es scheint ziemlich einfach zu sein, das System zu implementieren, das nach Updates in einem Netzwerk sucht und diese herunterlädt, wenn sie verfügbar sind. Dieser Teil des automatischen Updaters wird sich von Implementierung zu Implementierung erheblich ändern. Die Frage ist, welche unterschiedlichen Ansätze zum Anwenden von Patches bestehen. Nur Dateien herunterladen und alte durch neue ersetzen, ein heruntergeladenes Migrationsskript ausführen, Teile des Systems von Affen patchen usw.? Konzepte werden bevorzugt, aber Beispiele in Java, C, Python, Ruby, Lisp usw. sind willkommen.


6
Ich habe mir Googles Omaha angesehen . Könnte etwas zu sehen sein, wenn Sie noch interessiert sind (4 Jahre später ..)
funseiki

Antworten:


53

Ich denke, dass "sprachunabhängig" hier ein begrenzender Faktor sein wird. Anwendungen gibt es in so vielen Formen und Größen, dass es keine einheitliche Antwort gibt. Ich habe mehrere automatische Updater in mehreren Sprachen implementiert, und keine zwei waren ähnlich.

Die allgemeinste Philosophie ist, dass die Anwendung mit einem bestimmten Standort (Webadresse, Webabfrage, Unternehmensnetzwerkstandort usw.) nachfragt, ob die aktuelle Version oder die aktuellste Version ist. Wenn die Antwort ein Update erfordert, ist dieser Prozess für jede Situation unterschiedlich.

Eine beliebte Alternative besteht darin, den Heimatort einzuladen, ein Skript auszuführen, wenn die Anwendung gestartet wird. Das Skript kann beispielsweise die Version überprüfen, bei Bedarf Updates herunterladen und um Feedback zur Nutzung bitten.

Wir können wahrscheinlich besser helfen, wenn Sie die Parameter eingrenzen.

UPDATE: Der Ansatz zum "Patchen" hängt auch von der Art der Anwendung ab, und hier gibt es eine sehr große Vielfalt. Wenn Sie beispielsweise eine einzelne ausführbare Datei haben, ist es wahrscheinlich am praktischsten, die ausführbare Datei zu ersetzen. Wenn Ihre Anwendung viele Dateien enthält, sollten Sie nach Möglichkeiten suchen, um die Anzahl der ersetzten Dateien zu minimieren. Wenn Ihre Anwendung stark angepasst oder parametrisiert ist, sollten Sie sich bemühen, den Aufwand für die Anpassung zu minimieren. Wenn Ihre Anwendung interpretierten Code verwendet (z. B. eine Excel VBA-Anwendung oder eine MS Access MDB-Anwendung), können Sie möglicherweise Teile des Codes ersetzen. In einer Java-Anwendung müssen Sie möglicherweise nur eine JAR-Datei oder sogar eine Teilmenge des JAR-Inhalts ersetzen. Sie müssen auch die Möglichkeit haben, die aktuelle Client-Version zu erkennen und entsprechend zu aktualisieren. Ich könnte weiter und weiter machen, aber ich hoffe, Sie sehen meinen Standpunkt zur Vielfalt. Dies ist eine der vielen Situationen, in denen die beste Antwort normalerweise mit "Nun, es kommt darauf an ...!" Beginnt. Aus diesem Grund enthalten so viele Antworten "Bitte schränken Sie die Parameter ein."


20

Berücksichtigen Sie auch die Auswirkungen auf die Sicherheit, wenn Sie Informationen über das Update sowie die Update-Binärdateien selbst abrufen.

Vertrauen Sie der Quelle des Downloads? Sie rufen vielleicht zu Hause an, um Ihr Update zu erhalten, aber was ist, wenn sich in der Mitte ein Mann befindet, der auf einen böswilligen Server umleitet? Eine HTTPS- oder ähnliche sichere Verbindung hilft, es wird jedoch empfohlen, die Bits, die Sie eventuell herunterladen, mithilfe einer Überprüfung der digitalen Signatur zu überprüfen.


8

Zuerst benötigen Sie eine Datei auf Ihrer Homepage mit der neuesten Version. Ich denke, der beste Weg, eine spezielle SQL-Tabelle für diese Aufgabe zu haben und sie automatisch zu füllen, nachdem eine neue Version veröffentlicht wurde / die nächtliche Erstellung abgeschlossen ist. Ihre Anwendung erstellt einen neuen Thread, der einen integrierten http-Link mit der Version anfordert und mit dem aktuellen vergleicht. In .NET kann Code wie folgt verwendet werden:

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 diesem Beispiel ist version.php nur in einer einfachen Zeichenfolge wie 1.0.1.0 enthalten.

Ein weiterer Tipp, den ich geben kann - wie man ein Update herunterlädt. Die nächste Idee gefällt mir sehr gut: In den Ressourcen Ihrer Anwendung befindet sich eine CLR-Code-Zeichenfolge, die Sie im laufenden Betrieb (mit CodeDom) in einen temporären Ordner kompilieren. Die Hauptanwendung ruft sie auf und wird geschlossen. Der Updater liest Argumente, Einstellungen oder die Registrierung und lädt neue Module herunter. Und ruft die Hauptanwendung auf, die alle temporären Dateien löscht. Getan!

(Aber hier dreht sich alles um .NET)


6

Die einfachste Lösung (von vielen Programmen verwendet) besteht darin, das Deinstallationsprogramm für die vorherige Version und das Installationsprogramm für die neue Version auszuführen (optional werden Fragen übersprungen, die der Benutzer bereits beantwortet hat, wie z. B. die EULA). Der einzige Haken ist, dass die neue Version die Konfigurationsoptionen der alten Version lesen kann.

Unter Windows können Sie auch keine ausführbare Datei löschen, die gerade verwendet wird. Daher möchten Sie wahrscheinlich eine kleine ausführbare Datei im Ordner Temp ablegen, die den gesamten Prozess ausführt, und sie am Ende aus der Instanz der neuen Version löschen die gestartet wurde (oder registrieren Sie es einfach, um beim nächsten Neustart gelöscht zu werden ).


14
Während Sie eine verwendete EXE-Datei nicht löschen können, können Sie sie umbenennen. Lassen Sie die laufende Instanz sich selbst umbenennen, fügen Sie die neue Version hinzu und überprüfen Sie sie beim nächsten Start auf das Vorhandensein der umbenannten vorherigen Version und löschen Sie sie.
Oliver Giesen

Wow, das ist unglaublich! Danke für den Tipp!
Grey Panther

2

Am einfachsten wäre es, wenn Ihr Programm einen Server (eine Website) abfragt, um festzustellen, ob ein Update vorliegt. Wenn es ein Update gibt, können Sie dem Benutzer eine Nachricht anzeigen, die ihn zum Herunterladen einer neueren Version auffordert und einen Link bereitstellt.

Eine alternative und komplexere Lösung wäre die Erstellung eines kleinen Windows-Dienstes (oder Unix-Daemons), der regelmäßig überprüft, ob Updates vorhanden sind. Dieser Service kann das Update herunterladen und das Installationsprogramm starten.

Die allgemeine Architektur besteht darin, dass Sie einen zentralen Server haben, den Sie steuern und der die neueste Version kennt und wo Sie sie erhalten können. Dann fragen die Programme den Server ab. Ich werde keinen Beispielcode einfügen, da dieser auf dem Server und dem von Ihnen gewählten Format sehr schädlich ist. Es ist jedoch nicht schrecklich schwierig.


Die Frage, die ich gestellt habe (ich habe die Frage bearbeitet, um dies widerzuspiegeln), ist, wie Patches angewendet werden.
Nummer 1

2

Dies ist nicht so sehr eine vollständige Antwort, sondern ein Beispiel für einen Mechanismus zur automatischen Aktualisierung, den ich kürzlich implementiert habe. Die Situation unterscheidet sich ein wenig von der traditionellen Benutzeranwendung vom Typ Firefox, da es sich um ein internes Tool handelt, das bei der Arbeit verwendet wird.

Grundsätzlich ist es ein kleines Skript, das eine Warteschlange von Subversion-Zweigen verwaltet, die in einem Installationsprogramm erstellt und gepackt werden sollen. Es liest eine kleine Datei, in die die Namen der Zweige geschrieben werden, nimmt die erste, schreibt sie am Ende der Datei neu und startet den Erstellungsprozess, bei dem eine Reihe von Skripten aufgerufen werden. Die Konfiguration für jeden zu erstellenden Zweig wird in eine INI-Datei geschrieben, die zusammen mit dem Tool selbst in einem Subversion-Repository gespeichert wird.

Da dieses Tool auf mehreren Computern ausgeführt wird, wollte ich eine Möglichkeit haben, es auf allen Computern automatisch zu aktualisieren, sobald ich Änderungen am Tool selbst oder an den Konfigurationsskripten vorgenommen habe.

Die Art und Weise, wie ich es implementiert habe, war einfach: Wenn ich das Tool starte, wird es zu einer "äußeren Hülle". Diese äußere Hülle macht zwei sehr einfache Dinge:

  • svn update auf sich selbst und auf die Konfigurationsdateien
  • Starten Sie sich erneut, diesmal als "innere Shell", die tatsächlich eine Konfiguration verarbeitet (und dann wieder beendet).

Dieses sehr einfache System, mit dem ich mich selbst in einer Schleife aktualisieren kann, hat uns seit einigen Monaten sehr gute Dienste geleistet. Es ist sehr elegant, weil es in sich geschlossen ist: Der Auto-Updater ist das Programm selbst. Da die "äußere Shell" (der Auto-Updater-Teil) so einfach ist, spielt es keine Rolle, dass sie nicht von den Updates als "innere Shell" profitiert (die jedes Mal aus der aktualisierten Quelldatei ausgeführt wird).


Zu Ihrer Information, Metasploit verwendet auch "svn update" für den Update-Prozess.
Gray Panther

2

Eine Sache, die nicht wirklich erwähnt wurde, ist, dass Sie ernsthaft bedenken sollten, dass der Benutzer, der Ihr Programm ausführt, möglicherweise nicht über ausreichende Berechtigungen verfügt, um es zu aktualisieren. Dies sollte zumindest für Geschäftsanwender ziemlich häufig sein, wahrscheinlich weniger für Privatanwender.

Ich arbeite aus Sicherheitsgründen immer mit einem (selbst auferlegten) eingeschränkten Konto und es ärgert mich immer, dass die meisten automatischen Updater einfach davon ausgehen, dass ich als Administrator ausgeführt werde, und nach dem Herunterladen einfach fehlschlagen und keine andere Möglichkeit zur Ausführung bieten das Update, außer das Programm tatsächlich zu schließen und es in einem administrativen Kontext erneut auszuführen. Die meisten speichern das heruntergeladene Update nicht einmal im Cache und müssen es erneut ausführen.

Es wäre viel besser, wenn der automatische Updater bei Bedarf einfach nach Administrator-Anmeldeinformationen fragt und damit fortfährt.


1
Genau das macht unser Updater. wyUpdate (siehe: wyday.com/wyupdate ) ist ein in C # geschriebener Open Source-Updater.
Wyatt O'Day

1

Da die automatische Aktualisierung ein häufiges Szenario ist, steht in den meisten Sprachen mindestens ein Paket zur Verfügung, um dies zu unterstützen. (Unten liste ich einige der verfügbaren Pakete auf)

Eine der wirklich schönen Ideen ist das ClickOnce Distribution für .NET. Es handelt sich um ein Installationsprogramm, das Ihre Anwendung sandboxiert und im Benutzerkontext installiert, sodass keine Administratorrechte erforderlich sind. Sie können ClickOnce in Ihrer Veröffentlichung so konfigurieren, dass bei jedem Anwendungsstart nach Updates gesucht wird.

Java hat Java Web Start das die gleiche Funktionalität für Java-Applets bietet.

Delphi hat zahlreiche Artikel über die automatische Aktualisierung, Torry hat eine Liste von WebUpdate-Komponenten , zum Beispiel scheint GoUpdater einen sehr breiten Funktionsumfang zu haben.

Sie alle verwenden eine Website / Netzwerkfreigabe, um nach einer neuen Version zu suchen und dann entweder einen Patch oder eine vollständige Installationsdatei abzurufen und auszuführen. Sie sollten also versuchen, ein schönes Paket für Ihre Anwendung zu finden, um sich den Aufwand zu ersparen, Ihre eigene Lösung zu entwickeln und zu warten.


1

Ich werde eine Antwort für Windows annehmen.

Dieser Weg scheint gut zu funktionieren.


Führen Sie im Installationsprogramm Folgendes aus : 1. Erstellen Sie einen manuellen Startdienst, der als LocalSystem ausgeführt wird. Beim Start wird das Update dann gestoppt.
2. Ändern Sie die Dienstberechtigungen, damit alle Benutzer den Dienst starten können (wenn alle Benutzer in der Lage sein sollten, ohne Administratorrechte zu aktualisieren).
3. Ändern Sie das Hauptprogramm, um nach Updates zu suchen, wenn Sie mit einem einfachen Mechanismus starten. Wenn ein Update erkannt wird, fragen Sie, ob der Benutzer es anwenden möchte.
4. Wenn der Benutzer das Update akzeptiert, starten Sie den Dienst.

Wenn die Architektur dies zulässt, erstellen Sie eine Möglichkeit, das Update während der Ausführung zu überwachen.


1
Manueller Startdienst, der als LocalSystem ausgeführt wird und den alle Benutzer starten können? Das klingt nach einer Sicherheitskatastrophe, die darauf wartet, passiert zu werden.
Milan Gardian

1
Nur wenn das Aktualisieren der Software eine Sicherheitskatastrophe darstellt. Die Fähigkeit, einen Dienst zu starten, ist nicht die Fähigkeit, ihn anzugreifen, es sei denn, sie können in die Dienstbinärdatei schreiben.
Joshua

0

In einer Java-Webstart-Einstellung starten Sie eine JNLP-Datei, die dann den Download der Jar-Dateien auslöst, die zum Ausführen der Anwendung erforderlich sind. Bei jedem Webstart wird überprüft, ob es neuere Versionen der Jars gibt, und diese werden heruntergeladen, wobei die lokal zwischengespeicherten ersetzt werden. Mit einem Tool namens jardiff erstellen Sie nur Unterschiede zu den neueren Jars und verteilen diese über den Server (z. B. erhalten Sie nur ein Update).

Vorteile:

  • immer auf dem neuesten Stand

Nachteile:

  • Sie benötigen einen Anwendungsserver (Tomcat, JBoss), um die Dateien zu verteilen
  • Sie benötigen eine Internetverbindung, um die Anwendung zu erhalten

Beachten Sie nur, dass Sie nur einen Webserver benötigen, um die JARs zu verteilen. Tomcat ist einer dieser Server und implementiert auch die Servlet-Spezifikation.
Camilo Díaz Repka

0

Das Lesen der Antwort von Carl Seleborg gab mir einige Ideen, wie ein generisches Code-Repository nützlich sein könnte.

svn wird mit einem Tool namens svnsync geliefert, das sich wie ein svn-Export verhält, aber die tatsächliche Revision Ihres Exports verfolgt.

Jemand könnte dieses System verwenden, um nur die geänderten Dateien aus der tatsächlichen Revision des Benutzers abzurufen.

Tatsächlich haben Sie ein Repository mit den kompilierten Binärdateien, und wenn Sie svnsync ausführen, werden nur die geänderten Binärdateien abgerufen. Möglicherweise können auch lokale Änderungen an textbasierten Konfigurationsdateien mit neuen Konfigurationsoptionen zusammengeführt werden.


0

Die Funktion zum Installieren eines Patches in einem Programm ist im Grunde eine der Grundfunktionen eines Installationsprogramms. Installer-Software wird an zahlreichen Stellen dokumentiert, normalerweise jedoch pro Installer: Dort der Microsoft Installer (mit Install Shield Extensions), Ruby Gems , Java .jar- Dateien, die verschiedenen Linux-Paketmanagersysteme ( RPM , Apt-get ) und andere .

Dies sind alles komplexe Systeme, die das Problem des Patch-Programms im Allgemeinen lösen, jedoch für leicht unterschiedliche Systeme. Überlegen Sie sich, welches dieser Systeme Ihrer Anwendung am ähnlichsten ist, um zu entscheiden, welches für Sie am besten geeignet ist. Das eigene Rollen ist in Ordnung, aber das Betrachten dieser Systeme ist ein Ausgangspunkt.


0

Sie können ein internes Modul Ihrer Anwendung schreiben, um Aktualisierungen vorzunehmen. Sie können eine externe Mini-Anwendung schreiben, um Updates durchzuführen.

Schauen Sie sich auch die .NET-On-the-Fly-Kompilierungstechnologie an, mit der Sie eine solche Mini-Anwendung bei Bedarf on-the-fly erstellen können. Zum Beispiel http://fly.sf.net/



0

Wenn Ihre Software Open Source ist und sich an Linux oder Entwickler richtet. Es ist interessant, Ihre Software als Git-Repo zu installieren. Und wenn es gelegentlich oder jedes Mal, wenn es gestartet wird, den stabilen Zweig zieht.

Dies ist besonders einfach, wenn Ihre Anwendung über npm, sbt, mavan, stack, elm-package oder ähnliches verwaltet wird.


-1

Wenn Sie nach einer plattformübergreifenden Software-Update-Lösung suchen, besuchen Sie www.updatenode.com

Einige Highlights:

  • kostenlos für Open Source Projekte
  • Plattformübergreifendes und Open Source-Update-Client-Tool
  • bereits für die wichtigsten Sprachen lokalisiert
  • einfach zu integrieren und einfach zu handhaben
  • Cloud-basierte Verwaltungsplattform zum Definieren und Verwalten von Updates
  • bietet zusätzlich Unterstützung für die Anzeige von Nachrichten (informieren Sie über neue Ereignisse, Produkte usw.)
  • Das Webinterface ist geöffnet (Sie können Ihren eigenen Client mithilfe des Dienstes erstellen.)
  • Viele Nutzungsstatistiken, wie verwendete Betriebssysteme, Geostandort, Versionsnutzung usw.
  • Android API für mobile App-Updates

Probier es einfach.

Übrigens bin ich Teil des Entwicklerteams für den Open Source Client. :) :)


2
Arbeiten Sie für updatenode.com? Weil Sie einige alte Fragen beantwortet haben, die Sie empfehlen.
Crashmstr

Ich trage zur Entwicklung des Open Source-Clients bei: bitbucket.org/updatenode/unclient
sarahara

1
Sie sollten wahrscheinlich Folgendes lesen: Wie erwähne ich meine eigenen Produkte in Antworten?
Crashmstr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.