Entwickler-Ecke
Open Source Projekte - SJ Updater Utils 0.6 beta 1 - Updater für eigene Projekte
jaenicke - So 23.08.09 23:44
Titel: SJ Updater Utils 0.6 beta 1 - Updater für eigene Projekte
Hallo!
Nach den
SJ Config Utils [
http://www.delphi-forum.de/viewtopic.php?t=92348] zur Konfiguration von eigenen Projekten stelle ich dieses Projekt vor, mit dem man die eigene Anwendung einfach aktualisieren kann. Ohne zusätzliche Exe und mit korrekter Umsetzung mit der UAC unter Vista / 7.
Wichtig:
Sicherheitsmerkmale sind noch nicht vorhanden. Die downgeloadeten Updates werden also noch
nicht geprüft!
Features:- Direkte Integration in die Exe ohne zusätzliche DLLs oder Exe-Dateien.
- Anzeige des UAC-Prompts unter Vista
- Fortschrittsanzeige (noch nicht ganz flüssig)
- Demo-Projekt inkl. Update-Demo auf meinem Server
- Versionsangabe, damit Dateien nur bei Bedarf geladen werden
Lizenz:
MPL 1.1 oder LGPL 2.1 oder GPL 2.0 (oder höher)
Installation und Verwendung:
Die Zip-Datei auspacken und die Units dem Projekt hinzufügen. Dann die AppGuid in der Unit SJUpdaterUtils.pas ändern und die unter "Formatdefinitionen - Dateiliste online" beschriebene Updatedatei erstellen und hochladen, zusätzlich eine Datei mit der aktuellen Versionsnummer.
Dann muss nur noch wie im Demoprojekt eine Instanz der Klasse TSJAutoUpdater erstellt werden und die Eigenschaften zugewiesen werden. CheckForNewVersion prüft auf eine neue Version, StartUpdate startet dann das Update.
Meine Beispieldateien für die Demo sehen so aus (zum Test einfach einmal z.B. die Readme.txt löschen):
versioninfo hat folgendes geschrieben: |
1.6 |
Getestete Delphiversionen:
Delphi 2006 / Turbo Delphi, Delphi 2007 (andere Versionen funktionieren derzeit definitiv nicht!)
Indy 10 wird benötigt!
Getestete Windowsversionen:
2000, XP, Vista, 7
Windows 9x/ME wird definitiv nicht unterstützt. Der Aufwand aufgrund der unterschiedlichen Architektur wäre zu groß.
Bekannte Probleme:- Es werden kaum Fehlerprüfungen und keine Sicherheitsprüfungen durchgeführt!
Das Projekt habe ich auch hier vorgestellt:
http://www.delphipraxis.net/post1071944.html
http://forum.delphi-treff.de/showthread.php?p=198233
Schönen Gruß,
Sebastian
Nersgatt - Mo 24.08.09 14:09
Kurze Frage dazu. Ist es auch möglich, bei mehreren Updateschritten nur die Dateien zu übertragen, die wirklich benötigt werden? Beispiel: Unsere Anwendung besteht im großen und ganzen aus folgenden Teilen: Die EXE, einige Reports und SQL-Scripte, sowie einige DLL-Dateien.
Die EXE ändert sich bei jedem Update
Die Reports und Scripte ändern sich manchmal, aber nicht immer. Es kommen auch mal neue hinzu.
Die DLLs ändern sich praktisch nie.
Nun muss natürlich ein User, der ein Update von Version 1 auf Version 5 macht mehr Dateien runterladen, als ein User, der nur ein Update von Version 4 auf 5 macht. Unterscheidet dies Dein Tool?
Gruß,
Jens
jaenicke - Mo 24.08.09 22:42
Im Moment nicht, aber es ist ja kein großes Problem für jede Datei noch eine Versionsnummer hinzuzufügen. Dann kann man diese einfach vor dem Update vergleichen.
Ich bin mir da nur noch nicht im Klaren wie das sinnvoll zu lösen geht. Bei Exe-Dateien oder DLLs, kein Problem, die haben eine Versionsnummer. Aber bei anderen Dateien würde es schwieriger. Deshalb werde ich es für DLLs und Echsen relativ schnell einbauen, bei anderen mal schauen, wie das sinnvoll in Abhängigkeit von der Version z.B. der Exe lösbar ist. Das muss ich mir noch genauer überlegen, auch was die Zeiteinteilung der Projekte angeht.
Insbesondere werde ich da ein richtiges Dateiformat (XML z.B.) statt dem jetzigen unübersichtlichen Textformat einbauen, so dass man da auch mehr einstellen kann.
Nersgatt - Di 25.08.09 07:15
Meine Überlegung wäre, dass man ja nur speichern müsste, in welcher Programmversion jede Datei das letzte Mal geändert wurde. Z.B. in der angedachten XML-Datei. Nun kann der Updater schauen, welche Programmversion lokal vorliegt. Dann läd er die XML-Datei runter und schaut, bei welchen Dateien die Version > der lokalen Version ist und läd nur diese Dateien runter.
Für mich wird vermutlich zum Winter so etwas für unsere Anwendungen anstehen. Und da kommt jetzt bei mir die Überlegung auf, ob ich es selbst schreibe, oder evtl. auf Deine Arbeit aufbaue. Aber die Entscheidung hat noch etwas Zeit.
Gruß,
Jens
jaenicke - Di 25.08.09 09:12
Ich werde mir da einmal etwas überlegen. Das Problem ist, dass man dann jeder Datei eine eigene Versionsnummer geben müsste. Bzw. eine automatische Revisionsänderung wie auch hier im Forum bei Downloads bei einer Änderung. Wäre denn bei dir eine der beiden Möglichkeiten praktikabel? Also entweder manuell jeder Datei eine Version zuweisen oder in einem bestimmten Verzeichnis einen Vergleich an Hand der Hashes automatisch durchzuführen um ein neues Update zu erstellen.
Grundsätzlich ist es natürlich so, dass noch Hashes usw. ohnehin eingebaut werden, so dass man diese auch zur Versionsidentifikation nutzen kann.
Eine andere Frage ist natürlich, ob bei solchen ja vermutlich größeren Projekten ein externer Updater nicht besser wäre. Denn das wäre natürlich einfacher, weil da nicht so viel IPC notwendig wäre wie bei diesem integrierten Updater. Oder je nach Updatefrequenz und Zielgruppe vielleicht auch ein Dienst, der im Hintergrund läuft, damit keine Adminrechte angefordert werden müssen (falls es für Firmen gedacht ist, wo das wichtig wäre).
Nersgatt - Di 25.08.09 09:38
Nö, warum müsste man denn dann den Dateien Versionsnummern geben?
Man speichert nur in der Textdatei (oder XML, egal), in welcher Version die Datei das letzte mal geändert wurde. Ok, das ist eine Versionsnummer, hast Recht :D
Beispiel:
Datei1 letzte Änderung Version 3
Datei2 letzte Änderung Version 2
Datei3 letzte Änderung Version 2
Datei4 letzte Änderung Version 4
Der Update holt nun erst mal nur die Textdatei. Dann schaut er, welche Version vom Programm lokal vorliegt.
Fall 1: Lokal liegt Version 2 vor. Also sucht er alle Dateien, die > Version 2 sind. In dem Fall Datei1 und Datei4.
Fall 2: Lokal liegt Version 1 vor: Größer als Version 1 sind alle Dateien, also Datei1 bis Datei4
Fall 3: Lokal liegt Version 4 vor: Keine Dateien sind größer Version 4 -> Programm ist aktuell
So werden immer nur die Dateien runtergeladen, die der User wirklich braucht.
Dass die Versionsinformationen nur in den Textdatei gehalten werden hat den Charme, dass es mit allen Dateitypen funktioniert. Was natürlich NICHT geht, ist, ein Update auf Version 3 zu machen, obwohl Version 4 aktuell wäre. Aber wer will das schon. Dieses Vorgehen ist für uns praktikabel. Und falls ich es selbst machen muss, werde ich es vermutlich so machen. Natürlich wäre dafür eine kleines Hilfstool praktisch, das ich bei jeder Fertigstellung mit den geänderten Dateien füttere und das mir eine neue XML-Datei erstellt und den Krams hochläd.
Ein Dienst im Hintergrund ist für uns nicht nötig, es wäre sogar meiner Meinung nach unnötiger Ballast. So oft gibt es keine Updates. Im Schnitt machen wir während unserer Hauptsaison alle 2 Wochen ein Update, wobei nicht alle Kunden die Updates dann einspielen, weil es vielleicht nur Programmteile betrifft, die sie überhaupt nicht benutzen, oder wofür sie nicht mal eine Freischaltung haben. Außerhalb unserer Hauptsaison gibt es die Updates sporadischer und es gibt ein Jahresupdate, das wir auf CD versenden. Das wäre der Punkt, wo ich den Autoupdater einführen möchte. Den Updater in ein externes Programm zu packen kann man machen. Muss man nicht machen. Wäre mir persönlich egal.
Ein Punkt wäre für mich aber noch wichtig. Es müssten Unterordner unterstützt werden. Bei unsere Installationen liegen z.B. die Reports im Unterordner "Reports". Der Updater muss also die neuen Dateien in den richtigen Unterordner kopieren.
Jens
jaenicke - Di 25.08.09 09:42
Nersgatt hat folgendes geschrieben : |
Nö, warum müsste man denn dann den Dateien Versionsnummern geben?
Man speichert nur in der Textdatei (oder XML, egal), in welcher Version die Datei das letzte mal geändert wurde. |
Ok, stimmt. Das werde ich einmal einbauen.
Nersgatt hat folgendes geschrieben : |
Ein Punkt wäre für mich aber noch wichtig. Es müssten Unterordner unterstützt werden. |
Das ist bereits der Fall, man kann auch explizit Ordner anlegen oder löschen, wenn sich daran etwas ändert.
jaenicke - So 20.09.09 17:04
Es gibt eine neue Version, ich habe das wie versprochen eingebaut. ;-)
Neuerungen:
- Windows 2000 und XP werden auch voll unterstützt.
- Die Meldungen während des Updates können angepasst werden
- Die Anwendungsspezifische Guid funktioniert jetzt auch, wenn die Units zentral für mehrere Projekte verwendet werden
- Unterstützung von Delphi 2007 wurde erfolgreich getestet
- Durch eine Versionsangabe kann man jetzt erreichen, dass Dateien nur dann erneut geladen werden, wenn diese sich seit der installierten Version geändert haben (Idee von
Nersgatt)
- Das Anlegen und Löschen von Ordnern funktioniert jetzt korrekt
Ach ja: Und nebenbei habe ich Redundanzen entfernt und den Code etwas überarbeitet und übersichtlicher gestaltet. Zudem habe ich den Code besser kommentiert.
matze - Mo 21.09.09 11:35
jaenicke hat folgendes geschrieben : |
Windows 2000 und XP werden auch voll unterstützt. |
Was meinst du damit denn genau?
jaenicke - Di 22.09.09 00:12
Bei der ersten Alphaversion kam unter XP einfach nur "Zugriff verweigert", egal ob als Admin oder nicht. ;-)
Jetzt klappt es auch dort, dass Adminrechte angefordert werden usw.
Nersgatt - Di 10.11.09 10:06
Moin,
ich habe jetzt mal Zeit gefunden, mir das Projekt anzuschauen. Sieht erst mal ganz gut aus. Ich denke, ich werde noch ein paar Sicherheitsprüfungen einbauen (und die geänderten Versionen dann natürlich hier veröffentlichen).
Mir fehlen halt solche Checks, wenn z.B. die versioninfo-Datei gar nicht auf dem Server liegt, oder der Server nicht erreichbar ist, usw.
Hast Du mal versucht, ob man durch Angabe von Pfaden in der Form "..\..\..\explorer.exe" evtl. aus dem Rootverzeichnis der Anwendung ausbrechen kann und Dateien von anderen Programmen überschreiben? Ich denke, ich werde hier noch eine Prüfung einbauen, die die Verwendung von ".." in den Pfadangaben einfach verbietet und eine Exception wirft. Denn mir fällt kein "nicht bösartiger" Fall ein, in dem man ".." verwenden wollen würde.
Dann werde ich evtl. noch eine Prüfung einbauen, dass die Updatedateien in einem Unterordner relativ zur filelist und versioninfo liegen müssen. Jetzt im Moment würde es reichen, irgendwie in den Server einzubrechen und in der filelist einen Eintrag in der form update;http://sehrBöserServer.böse/bösedatei.exe;bösedatei.exe zu erstellen. Und schwupps läd der Updater böse Dateien aus Fernost nach. :shock:
Ansonsten ist es aber schon dass, was ich mir vorgestellt habe. Gute Arbeit! :zustimm:
Gruß,
Jens
BenBE - Di 10.11.09 11:10
Würde der Updater mit einem entsprechenden, asymmetrischen Verfahren arbeiten, würde sowas auffallen, da deine manipulierte Liste keine gültige Signatur mehr hätte.
Zudem sollte man eh die heruntergeladenen Dateien mit signiren.
jaenicke - Di 10.11.09 11:36
Das würde ich auch gerne einbauen, habe aber bisher noch nichts mit solchen Sicherheitsvorkehrungen gemacht. Deshalb hatte ich bisher nicht die Zeit dazu mir anzuschauen wie sowas eigentlich korrekt umgesetzt wird. :wink:
Denn wenn ich da irgendwas implementiere bringts auch nicht viel. Außer zumindest eine gewisse Integritätsprüfung zu haben.
Nersgatt - Fr 13.11.09 09:36
Moin,
ich habe mich nun entschlossen, dein Projekt nicht einzusetzen. Ich habe selbst einen Updater programmiert. Ich möchte auch kurz auf die Gründe eingehen.
- Mir gefällt das Konzept nicht, dass sich die Anwendung ständig selbst neu startet mit verschiedenen Parametern. Da ich einen eingenständigen Updater brauche, der auch Programme, die in anderen Sprachen geschrieben sind (z.B. VB.NET), updaten kann, kann ich den Updater gleich Adminrechte anfordern lassen (über ein entsprechendes Manifest). Das macht die ganze Sache ungleich einfacher.
- Dein Updater geht davon aus, dass es in einem Projekt nur eine EXE-Datei gibt, die auch Updater-Funktionalität beinhaltet (vgl. setzen der Variable FMainExecutable). Mein Projekt besteht zur Zeit aus 10 EXE-Dateien. Hier müsste ich die Arbeitsweise Deines Updater ändern, damit das mit meinem Projekt zusammenarbeitet
- Dein Updater soll ja in die Anwendung integriert werden. Dabei startet der Updater die Anwendung mehrfach mit verschiedenen Parametern neu. Der Updater geht davon aus, dass die Anwendung selbst keine Parameter verwendet. Meine Anwendung kann schon jetzt mit verschiedenen Parametern gestartet werden, die verschiedene Dinge in der Anwendung auslösen. Die Parameter des Updaters in meine Anwendung zu integrieren wäre in nicht unerheblicher Aufwand.
- Mir fehlen einige Funktionen. Z.B. möchte man doch dem User anzeigen, welche Version im Internet verfügbar ist. Lässt sich natürlich einbauen, aber das sauber in Dein Programmkonzept zu integrieren ist auch Aufwand.
- Einige kleine Bugs sind wohl auch noch drin. VerToInt ignoriert z.B. das letzte Zeichen des Versionstrings. Dies muss man alles debuggen und korrigieren. Du wirst mir sicher zustimmen, dass es einfacher ist, eigenen Code zu debuggen. Bei fremden Code muss man sich erst reindenken, was sich der Programmierer dabei gedacht hat.
Alles in allem bin ich zu dem Schluss gekommen, dass ich schneller meinen Updater genau so bekomme, wie ich ihn möchte/brauche, wenn ich es komplett selbst schreibe, was ich nun auch getan habe.
Mein Updater setzt auf folgende Konzept
- Eigenständiger Updater
- Fordert beim Start Adminrechte an
- Download der Dateien in einem Temp-Ordner, dann die Dateien installieren, temp-Dateien löschen.
- Der Updater erstellt beim Programmstart einen Mutex. Damit wird verhindert, dass die Hauptanwendung gestartet wird, während der Updater aktiv ist. Außerdem wird verhindert, dass der Updater 2x gleichzeitig läuft. Wäre in Deiner Version komplizierter implementierbar, weil sich die Anwendung selbst neu starten können muss.
- In der Dateiliste (filelist) wird er Pfad zu den Remotedateien relativ zur filelist angegeben. Das verhindert, dass Dateien von anderen Servern geladen werden. Außerdem ist es so einfach möglich, den Pfad zu dem ganzen Updatekrams auf dem Server zu ändern, in dem man die Dateien einfach verschiebt. Bei Deiner Version müsste man die Pfade in der filelist anpassen.
Bitte nicht falsch verstehen, Deine Arbeit ist sicherlich für einfache Projekte gut, aber für meine Zwecke einfach nicht das Richtige. Ich möchte Deine Arbeit mit diesem Posting auch nicht schlecht reden, sondern nur einige Punkte aufzeigen, an die man denken muss/kann, bzw. die man besser machen könnte.
Gruß,
Jens
kalmi01 - Fr 13.11.09 17:11
Hallo Jens,
so einen Updater, wie Du ihn beschreibst habe ich mir schon vor Jahren gebastelt.
ABER beide Ansätze haben ihre Berechtigung.
Manchmal will man ja wirklich nur die eine Exe updaten, dann ist so ein eigenständiger Updater je nach dem wie komfortabel er ausgebaut ist, schon ein wenig überdimensioniert.
Wie gesagt, BEIDES hat seine Berechtigung !
Gruss
Michael
Alois1 - Di 11.05.10 03:32
Hi Sebastian,
ich habe gerade deinen SJ-Updater getestet.
Die Demo-Version zum Herunterladen unter
http://www.sj-berlin.de/updater/updatedemo/SJUpdUtilsDemo.exe
scheint viel flüssiger zu laufen, als die im Source-Code (z.B. ProgressBar).
Ausserdem bleiben bei der compilierten Version drei Fenster nachdem Update offen. (Das Fenster des alten Programms, des neuen Programms und der Meldung "Das Update wurde erfolgreich beendet")
Bei deiner Version auf der Homepage nicht. Hast Du deinen Code weiterentwickelt?
Wäre nett wenn du hier den aktuellen Code posten könntest.
Gruss und Danke im vorraus Alois ;)
jaenicke - Di 11.05.10 08:44
Ich habe die neue Version noch kurz überarbeitet und hochgeladen. Leider passten die Versionen nicht zusammen, deshalb die Fehler beim Update.
Ich hatte im Zuge eines anderen Projekts an dem Updater gearbeitet und dabei vergessen auch dieses Projekt zu aktualisieren. :oops:
Ja, was ist neu: Es läuft alles ein wenig flüssiger und es werden nicht mehr unnötige Fenster angezeigt.
Zwei Probleme gibt es noch:
Erstens hängt das Programm, wenn die Internetverbindung schlecht ist und beim Update abbricht.
Zweitens werden Textdateien nicht "as-is" heruntergeladen sondern kommen (bei meinem Server) mit UNIX-Zeilenumbrüchen an.
Erledigt, das war nur ein Problem beim automatischen Upload.
Ich plane allerdings ohnehin gepackte Updatedateien zu verwenden, das erschlägt dann gleich mehrere Probleme (CRC-Check + kleinere Dateien). Wann ich dazu komme weiß ich allerdings noch nicht.
Alois1 - Di 11.05.10 08:50
Hi Sebastian,
vielen Dank für die schnelle Antwort. Werde die neue Version gleich mal testen.
Gruss Alois ;)
jaenicke - Di 11.05.10 09:04
Ich arbeite auch gerade noch daran, vielleicht schaffe ich es in den nächsten Stunden noch weiterzukommen was die geplanten Features oder die beiden das Problem angeht. ;-)
Diesmal werde ich aber die Onlineversion nicht mehr durcheinander bringen. :mrgreen:
Alois1 - Di 11.05.10 10:40
Wenn ich das Programm kompiliere (D2010) und starte erhalte ich nach der Meldung "Das Update wurde efolgreich beendet!" immer einen EAccessViolation.
Anscheinend beim Schliessen des alten Programms.
In Deiner DEMO (vorkompilierten Exe) passiert das nicht.
jaenicke - Di 11.05.10 10:51
Das wird an Unicode liegen. Leider habe ich selbst nicht Delphi 2010, deshalb ist es nicht so einfach das zu testen (deshalb stehen auch als Delphiversion nur 2006 und 2007 dabei, eben wegen Unicode und ggf. Problemen damit).
Ich schau mal ob ich herausfinde woran das liegt. Ich werde einfach einmal die Trial ziehen und debuggen was da eigentlich passiert.
// EDIT:
Der Fehler tritt beim Beenden der alten Instanz auf, ich werde nachher noch eine aktualisierte Version veröffentlichen.
// EDIT2:
Hmm :gruebel:, ich muss da noch ein wenig testen, so auf Anhieb sehe ich das Problem nicht.
jaenicke - Mi 12.05.10 21:01
Es gibt eine neue Version, jetzt mit recht flüssiger Fortschrittsanzeige, ein Bug bei der Abstimmung via IPC ist behoben, außerdem gibt es komplette Unterstützung der aktuellsten Indy Version (alte ab Version 10 gehen über einen Compilerschalter aber weiterhin auch). Diese Version veröffentliche ich als Beta 1, da diese soweit stabil läuft auf den angegebenen Plattformen und mit den angegebenen Delphiversionen.
Die Beta 2 wird dann alle geplanten Features wie eine Packfunktion und parallelisierte Downloads enthalten.
Leider konnte ich auch nach längerer Fehlersuche den Fehler unter Delphi 2010 nicht finden. Es funktioniert also derzeit mit Delphi 2009 und 2010 nicht. Ich kann nur vermuten, dass da irgendetwas am Speicher oder bei der Threadsynchronisation schief geht. Das untersuche ich noch, kann aber keine rasche Lösung in Aussicht stellen, da ich wirklich noch keine Idee habe was das Problem ist.
Was passiert: Die erste Instanz stürzt ab nachdem das Update eigentlich bereits durch ist. Beim Beenden gibt es dann eine Exception beim Aufräumen nach OnDestroy des Formulars. Zudem gibt es einen Zugriffsfehler bei den Updateroutinen, wenn diese bei Indy aktiviert sind, vermutlich beim Zugriff auf die Fortschrittsanzeige. Das lässt mich auf die genannten beiden Probleme als mögliche Ursache tippen.
Alois1 - Mi 12.05.10 21:43
jaenicke hat folgendes geschrieben : |
Es funktioniert also derzeit mit Delphi 2009 und 2010 nicht. |
Schade eigentlich. Ich habe mich auch schon versucht den Fehler zu finden... aber bei deinem Programm stosse ich leider an meine Grenzen.
Wäre toll wenn es eine Version für D2010 geben würde.
Ich sage trotzdem brav Danke für deine Bemühungen und deine tolle Arbeit bisher.
Gruss Alois ;)
PhilDelphiNew - Mo 07.06.10 14:45
Hallo :)
Dein Update Programm ist wirklich sehr gut und einfach zu handhaben! In wenigen Minuten hatte ich mein erstes Update erstellt!
Leider habe ich einen Fehler festgestellt. Wenn ich nach dem ersten Update ein zweites Update erstelle (Erstes Update Versionsnummer 1.0, zweites Update 1.1) und anschließend den Updater starte, scheint zunächst alles zu funktionieren. Nur werden dann alle Dateien, bis auf die aus dem Update 1.1 gelöscht! Nur die alten Verzeichnisstrukturen bleiben erhalten!
Ich habe es mehrere Male getestet und auch im 2. Update probeweise die "createfolder" Befehle rausgenommen, geht aber trotzdem nicht.
So (ohne Createfolder-Befehle) ist meine Updatefilelist Struktur:
Update 1.0:
update;
http://XXAutoupdater.exe;XXAutoupdater.exe
1.0;update;
http://YYY/YYYY.YY;YYYY.YY
Update 1.1:
update;
http://XXAutoupdater.exe;XXAutoupdater.exe
1.1;update;
http://XXXXXX/XXXX.xx;XXXX.xx
1.0;update;
http://YYY/YYYY.YY;YYYY.YY
Nach dem Update 1.1 ist dann also die YYYY.YY verschwunden: ,nur die XXXX.xx ist vorhanden. Der Updater nennt die alten Dateien in (.bak) und löscht sie dann... das programm behandelt die Dateien aus dem letzten Update als "alt" und löscht sie dann.
Geplant habe ich einen Updater, der egal auf welcher Version die Clients sind, immer auf die neueste Version updaten kann, ohne dabei alle Dateien neu runterzuladen!
So soll sich die Fileliste mit fortlaufender Versionsnummer immer erweitern und sowohl dem 1.0er als auch den 1.1, 1.2, 1.3ern etc. ein Update auf die neueste (zum Beispiel 1.5) ermöglichen!
Ist das umsetztbar mit diesem Updater? Ich denke eigentlich schon, nur funktioniert es nicht so, wie ich es probiert habe. Vielleicht ein Fehler im Programm?
Vielen vielen Dank für das tolle Programm und das Du es kostenlos online gestellt hast!
LG
Phil
////EDIT: Könnte man einstellen, dass nur die Dateien umbenannt werden, die in der Filelist aktueller sind, als die auf dem PC?
Hier der Code, ich glaube daraus zu lesen, dass alle Dateien aus der Filelist mit den Operatoren "update" und "delete" umbenannt werden.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| begin for i := 0 to FDownloadFileList.Count - 1 do begin CurrentPath := FRootPath + FDownloadFileList.LocalPath[i]; if (FDownloadFileList.Operation[i] in [upoDeleteFile, upoUpdateFile])
<-------- HIER müsste dann eine Klausel stehen das nicht alle mit Operator UpdateFile umbenannt werden, sondern nur die Werte, die größer sind, als die Version auf dem PC --------->
and FileExists(CurrentPath) then RenameFile(CurrentPath, CurrentPath + '.bak'); SendMessage(FProgressMsgTarget, WM_UPDATEPROGRESS, 0, (i + 1) * 100 div FDownloadFileList.Count); end; end; |
Leider kann ich nicht programmieren. Könnte mir jemand helfen?? Vielen Dank :)
Moderiert von
Narses: Delphi-Tags hinzugefügt
jaenicke - Di 08.06.10 08:30
Hallo und :welcome: hier im Forum ;-)
Danke für das Feedback, dort habe ich leider wirklich die Prüfung vergessen. Ich glaube das hier sollte das korrigieren, leider muss ich gleich zur Arbeit und kann es deshalb nicht gleich auch testen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TSJAutoUpdateStep1.RenameCurrentFiles(); var i: Integer; CurrentPath: string; begin for i := 0 to FDownloadFileList.Count - 1 do begin CurrentPath := FRootPath + FDownloadFileList.LocalPath[i]; if (FDownloadFileList.Operation[i] in [upoDeleteFile, upoUpdateFile]) and FileExists(CurrentPath) and ((CompareVersions(FCurrentVersion, FDownloadFileList.RenewVersion[i]) < 0) or (FDownloadFileList.RenewVersion[i] = 0)) then RenameFile(CurrentPath, CurrentPath + '.bak'); SendMessage(FProgressMsgTarget, WM_UPDATEPROGRESS, 0, (i + 1) * 100 div FDownloadFileList.Count); end; end; |
Das werde ich hoffentlich noch heute Abend auch selbst testen und dann eine neue Version damit hochladen. Aber ich poste es schon einmal, vielleicht ist damit ja schon einmal alles ok. Rein logisch sollte es so richtig sein: Die Datei wird nur noch gelöscht (bzw. hier dafür umbenannt), wenn die aktuelle Version kleiner als die in der Updatedatei angegebene ist oder dort keine angegeben ist und die Datei lokal überhaupt existiert.
PhilDelphiNew - Di 08.06.10 15:13
wow, vielen Dank für die schnelle Antwort und den neuen Code!
Nun klappt das Updaten richtig, es werden keine Dateien mehr gelöscht, die schon vorher im Programm waren. Klasse :)
Nur eine Kleinigkeit ist nun neu aufgetreten. Die Instanzen des Updater beenden sich nicht mehr nach dem Update und es kommt auch keine Meldung mehr, dass das Update erfolgreich verlaufen ist. Nach dem Update schließt sich das Programm, es bleibt aber noch im Taskmanager und somit können wohl die nächsten Schritte nicht eingeleitet werden. Am Ende habe ich dann 2 updater im Taskmanager laufen.
Das ist hoffentlich nur eine Kleinigkeit.
Nochmals vielen Dank für das tolle Programm und Deine Hilfe :)
LG
Phil
jaenicke - Di 08.06.10 17:32
Ich weiß woran das liegt. Und zwar nimmt das Programm die erste Backupdatei als Maß wann das Update durch ist. ich kann mich daran erinnern, dass ich glaube ich gar nicht teste ob die Datei existiert, sondern nur warte bis ich sie erfolgreich löschen konnte.
Und wenn da jetzt eben diese nicht zu aktualisierende Datei bzw. deren Backupdatei versucht wird zu löschen, dann geht das natürlich nicht. Weil es die gar nicht gibt. Da fehlt also noch die selbe Prüfung wie sie an der anderen Stelle ergänzt wurde. Das ist also "nur" eine Folge der anderen Änderung.
Da ich derzeit auf Arbeit bin (hab Pause :D) kann ich das nicht gleich anschauen, das mache ich dann heute Abend, ich komme gegen Mitternacht nach Hause. ;-)
PhilDelphiNew - Di 08.06.10 23:30
Oh Mensch, Du arbeitest aber lange! Ich dachte schon, wenn ich um 19Uhr zu Hause bin, dass ich spät dran bin :-D
Ich finde Deinen Updater klasse und wenn dieser kleine Fehler behoben ist, werde ich ihn auch ganz sicher einsetzen!
jaenicke - Mi 09.06.10 07:26
Ich habe es jetzt auf mehreren PCs getestet (gestern habe ich nur gemerkt, dass es bei mir geht --> Testen kann dauern :D), aber das Problem konnte ich nicht reproduzieren. Welche Delphiversion und welches Betriebssystem ist das denn?
Passiert das nur mit deinem eigenen Programm oder auch mit meiner Demo? Ich habe mit der Demo deine Updateversionskonstellation versucht nachzustellen (1.4 ist die aktuelle, 1.6 und 1.0 haben die beiden Textdateien, die geladen werden), aber es klappt überall alles. :nixweiss:
Ich habe auf jeden Fall eine Version mit dem ersten Bugfix hochgeladen, der ist also auch bei der Downloadversion behoben.
PhilDelphiNew - Mi 09.06.10 15:52
Ich benutze windows7 64 (ich habe integer und int64 in deinem Updater getauscht) und habe Delphi2007 (CodeGear™ Delphi® für Microsoft® Windows™ Version 11.0.2627.5503)
Als ich deine Beta2 runtergeladen habe und dann erneut meine Änderungen vorgenommen habe, haben sich die Programme nach dem Update dann auch richtig geschlossen und die .bak Dateien gelöscht.
Jetzt ist mir etwas anderes aufgefallen. Wenn ich mehrere (auch etwas größere Dateien bis zu 5MB) updaten lasse, werden einige Falsch umbenannt und so wird der Inhalt der "skin.tga" plötzlich in die "live.msh" getauscht. Die Dateieinamen bleiben jedoch korrekt, auch bleiben sie in der richtigen Verzeichnisstruktur. Das passiert sowohl mit der Beta1 als auch mit der Beta2.
Wenn das Problem nicht sofort erkennbar ist, schicke ich auch gerne ein Beispielupdate.
Eine andere, rein kosmetische, Sache ist der Fortschrittsbalken für das downloaden der Dateien. Ich habe rund 500 Dateien zum runterladen (im ersten Update), der Fortschrittsbalken ist jedoch schon nach den ersten paar Dateien bis 100% angestiegen und bewegt sich dann auch nicht mehr (logisch) bis alle Dateien runtergeladen sind.
LG
Phil
jaenicke - Mi 09.06.10 16:07
Int64 und Integer sollte soweit ich mich erinnere auch durch eine Compilerdirektive direkt oben in der unit behoben werden können. Oder erinnere ich mich da falsch? :gruebel:
Das genannte Problem kann ich mirn erst einmal nru erklären, dass da in der Updatedatei selbst die Dateinamen falsch stehen. Ich hatte das Problem in meinen Tests bisher jedenfalls nicht. Und ich hatte auch beispielinhalte drin um zu sehen welche Dateien bei verschiedenen Versionen aktualisiert werden und welche nicht.
Ich schaue mir das dann heute Abend noch einmal an. Ein reproduzierbares Beispiel wäre da sehr hilfreich, das kannst du mir auch gerne per PN schicken, wenn du es hier nicht veröffentlichen möchtest.
Zum Fortschrittsbalken: Der ist noch nicht ideal, das stimmt, ich schaue es mir an.
PhilDelphiNew - Fr 11.06.10 20:39
Achso, wie man etwas in der compilerdirektive veränder weiß ich nicht, ich habe die Werte einfach vertauscht ... nicht sehr schlau denke ich ;)
Zu dem Statusbalken: Könnte man einfach die Dateien in der filelist zählen lassen und den Fortschrittsbalken nach dieser Zahl wachsen lassen? Ich denke, dass das andere Programme auch so machen, z. B.: QSetup.
Ich habe das laue Gefühl, dass etwas mit meinen Einstellungen nicht so stimmt. Ich werde Delphi jetzt noch auf einen anderen PC installieren und neu starten. Wenns dann noch nicht klappt, poste ich hier ein Beispiel Update zum Reproduzieren.
Vielen Dank nochmals für die Hilfe bisher! :)
LG
Phil
jaenicke - Fr 11.06.10 21:05
PhilDelphiNew hat folgendes geschrieben : |
Achso, wie man etwas in der compilerdirektive veränder weiß ich nicht, ich habe die Werte einfach vertauscht ... nicht sehr schlau denke ich ;) |
Delphi-Quelltext
1: 2:
| {$message hint 'If you get the error Incompatible types: ''Int64'' and ''Integer'' then toggle this define!'} |
Den Punkt weg und schon gilt die Direktive, setzt du ihn wieder ist das ein normaler Kommentar (wie jetzt).
jaenicke - So 27.03.11 22:56
PhilDelphiNew hat folgendes geschrieben : |
Jetzt ist mir etwas anderes aufgefallen. Wenn ich mehrere (auch etwas größere Dateien bis zu 5MB) updaten lasse, werden einige Falsch umbenannt und so wird der Inhalt der "skin.tga" plötzlich in die "live.msh" getauscht. Die Dateieinamen bleiben jedoch korrekt, auch bleiben sie in der richtigen Verzeichnisstruktur. |
Ich habe es nicht genauer getestet, aber ich denke ich habe das Problem mit der jetzt neuen Version behoben.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!