Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Updater aktualisieren
*neo*
myCSharp.de - Member



Dabei seit:
Beiträge: 301

Themenstarter:

Updater aktualisieren

beantworten | zitieren | melden

Hallo zusammen,

ich habe mir einen kleinen Updater geschrieben, der eine neue Version meines Hauptprogramms vom Server lädt und die Programmdatei direkt beim download überschreibt:

webClient.DownloadFileAsync(new Uri("http://domain.de/update/hauptanwendung.exe"), "hauptanwendung.exe");

Damit wird die Datei des Hauptprogramms direkt überschrieben. Da sehe ich das Problem, wenn die Datei falsch runtergeladen wurde oder korrupt ist. Dann ist die Original Datei vom Hauprogramm kaputt. Wie seht ihr das?

Wie mache ich aber ein Update vom Updater? Der Updater läuft ja und kann somit nicht überschrieben werden. Wir macht ihr das denn? Eine Möglichkeit wäre meiner Meinung nach, dass der Updater seine Programmdatei selbst lädt, aber sich nicht überschreibt sondern dieses in ein unterverzeichnis schreibt. Nach dem die Datei dort abgelegt wurde beendet sich der Updater und startet noch schnell eine Batch-Datei die den neuen Updater in das Hauptverzeichnis verschiebt.

Die Lösung würde wahrscheinlich gehen, ist aber nicht so schön.

Grüße
private Nachricht | Beiträge des Benutzers
Darth Maim
myCSharp.de - Member



Dabei seit:
Beiträge: 230

beantworten | zitieren | melden

Benenne die hauptanwendung.exe vor dem updaten in hauptanwendung.old.exe oder so um, dann hast du die alte lauffähige Version immer noch als Backup. Das gleiche kannst du zum Updaten des Updaters benutzen, nenne die Datei des Updaters um (geht auch während der Updater läuft), und dann kannst du den neuen Updater an die Stelle des alten Laden. Und im Updater (oder in der Hauptanwendung) kannst du beim Starten prüfen ob eine dieser *.old.exe Dateien vorhanden ist und wenn ja, dann löschen, da das Programm ja grade läuft und du so weißt, dass die Datei nicht korrupt ist. Natürlich kannst du die *.old.exe-Dateien auch behalten, und nur löschen wenn du sie neu anlegst.

Darth Maim
private Nachricht | Beiträge des Benutzers
muntablues
myCSharp.de - Member



Dabei seit:
Beiträge: 231
Herkunft: AUT

beantworten | zitieren | melden

Ich lese beim Programmstart ein Textfile auf dem Server und schau ob ne neuere Version oben ist. Falls ja wird das komplette Setup runter geladen. Wenn das herunten ist, starte ich das Setup und beende das Programm.

Nun kann der User einfach den Installer durch klicken und am Schluss wieder starten.

Das finde ich relativ sicher und man braucht keinen extra Updater schreiben.
______________________________
Gruß MB

Home of DigiJay - DJ-Freeware
private Nachricht | Beiträge des Benutzers

Moderationshinweis von herbivore (25.01.2013 - 03:09:23):

Das Thema Updater wurde im Forum ausgiebig behandelt, inkl. der Thematik, eine Datei zu ersetzen, die "in use" ist. Bitte benutze die Forumssuche. Gute Treffer oder ein Ergebnis kannst du natürlich gerne posten.

Auf den Punkt, dass die ausführbare Datei nicht überschrieben werden soll, bevor der Download vollständig abgeschlossen ist, wird in den anderen Threads möglicherweise nicht eingegangen, aber nur, weil das trivial zu lösen ist. :-)

*neo*
myCSharp.de - Member



Dabei seit:
Beiträge: 301

Themenstarter:

beantworten | zitieren | melden

Hallo zusammen,

ich habe es jetzt wie folgt gemacht. In der Hauptanwendung sorge ich für den Download der neuen Updates in ein Verzeichnis "download" im Programmverzeichnis. Ist der Download abgeschlossen starte ich das Updateprogramm und beende die Haupanwendung mit folgendem:


System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = Application.StartupPath + @"\Updater.exe";
process.Start();

Application.Exit();

Daraufhin wird der Updater gestartet, der zuerst die alten Programmdateien umbenennt (ich hänge einfach an das exe ein _old, also so: .exe_old), dann die neuen Programmdateien aus dem Ordner "download" eine Ebene nach oben, in das Programmverzeichnis, verschiebt und dann zum Schluß noch das Verzeichnis "download" löscht. Im Anschluß wird das Haupprogramm wieder gestartet mit folgendem:

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = Application.StartupPath + @"\Haupanwendung.exe";
process.Start();

Application.Exit();

Nach dem Start der Haupanwendung prüfe ich im Konstruktor ob es Dateien mit der Endung .exe_old. Wenn ja, lösche ich diese. Das hat auch soweit funktioniert.

Leider ist mir gerade eben noch einmal beim Testen aufgefallen, dass es leider doch nicht immer funktioniert. Ich erhalte manchmal beim Löschen der alten Programmdateien eine "system.unauthorizedaccessexception der zugriff auf den pfad...". Ihrgend wie scheint es damit zu tun zu haben das die Hauptanwendung beim ersten mal schließen mit Application.Exit(); nicht schnell genug geschlossen wir nach dem Runterladen der Dateien. Ich schätze mal der Prozess ist ihrgend wie noch offen. Der Updateprozess scheint zu schnell beendet zu werden.

Ich wollte eigentlich nur die Lösung posten, aber der Fehler kam bisher nicht.

Grüße
private Nachricht | Beiträge des Benutzers
schlumpf2009
myCSharp.de - Member



Dabei seit:
Beiträge: 12
Herkunft: stuttgart

beantworten | zitieren | melden

probiere mal bitte den umweg

1. erstelle eine 1*.bat datei die dir deine updater exe startet
2. erstelle eine updater exe die dir beim start die 1*.bat und die programm.exe löscht
3. wenn die updater.exe die 2 dateien gelöscht bekommen hat ( system.file.info ... file exist )
dann lade die neue programm.exe herunter
4. erstelle eine 2*.bat die dir deine hauptanwendung startet
5. beende die updater.exe und starte die 2*.bat
6. prüfe in deiner programm .exe ob die 2*.bat und die updater.exe noch da sind und lösche sie

7. sollte fertig sein


edit : was du aber auch machen kannst, der 1*.bat datei sagen "del programm.exe" dann bekommst du keine exception ;)

edit2 : 1*.bat und 2*.bat sind 2 untereinander verschiedene bat dateien mit einem freiwählbaren namen
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von schlumpf2009 am .
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

beantworten | zitieren | melden

Ich würde einen ähnlichen Weg einschlagen nur macht es Sinn die Architektur anders zu wählen :

Eine Exe die nur die Dlls. lädt und als Basis nutzt.
Beim Update wirst du die Exe nie bzw. selten Updaten.
Beim laden der Assemblys prüft man ob diese korrupt sind.
So kommst du nie bzw. seltener in Probleme, dass dein Hauptprogramm korrupt ist.

P.S. Nutze dochd as UpdateSystem.net ;-)

Grüße
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo *neo*,
Zitat
Irgend wie scheint es damit zu tun zu haben das die Hauptanwendung beim ersten mal schließen mit Application.Exit(); nicht schnell genug geschlossen wir nach dem Runterladen der Dateien.

damit musst du natürlich immer rechnen. Aber da hilft nichts anderes als zu warten, wenn die Exception kommt, und es etwas später noch mal zu probieren.

Natürlich kann es helfen, das Process.Start ans Ende des Mains zu verschieben. Dann wird der Prozess erst im letzten möglichen Moment gestartet. Aber selbst dann kann es sein, dass der neu Prozess schneller gestartet ist, als der alte beendet. Das Warten solltest bzw. musst du also trotzdem implementieren.

herbivore
private Nachricht | Beiträge des Benutzers