Autor |
Beitrag |
bruce185
      
Beiträge: 283
winXP
D7 Ent
|
Verfasst: Sa 10.01.09 20:30
Hallo,
wie mache ich ambesten ein Update funktion für mein Programm?
Also, es soll nach neuere Version geprüft werden, wenn vorhanden, dann soll die .exe Datei vom Server heruntergeladen und anschließend ersetzt werden.
Was mich Interessieren würde, wie man auch die .exe Datei überschreiben kann?
Eigentlich kann das ja nicht so leicht funktionieren, da die .exe Datei ja verwendet wird.
Man könnte das ja so machen:
Die .exe Datei vom Server in ein Temp Ordner herunterladen, nach beendigung des heruntergeladenen Datei Programm beenden, Datei im Verzeichniss Kopieren, indem sich das Programm befindet und dann das Programm wieder starten.
Könnte man das so realisieren, das es alles automatisch gemacht wird oder gibt es einen besseren Weg?
Vielen Dank schonmal.
MfG Moderiert von Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Sa 10.01.2009 um 23:55
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 11.01.09 10:48
ich hab das so realisiert:
Wir das Programm gestartet, wird nicht die eigentliche exe sonder eine Updater.exe gestartet. Die ist nur dazu da zu gucken, ob ne neue Version auf dem Server ist. Diese kopiert ggf. die neue exe runter und startet diese dann.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 11.01.09 10:56
Und noch cooler  ist es, wenn das Programm eine Batch-Datei anlegt, die die Kopierfunktionen durchführt, diese startet, sich beendet und nach Durchlauf wieder das Programm startet. Das ist sehr einfach zu realisieren (Stringlist) und es muss keine zusätzliche Exe mitgeliefert werden.
Zur Prüfung ob eine neue Version vorhanden ist, legt man sich eine Textdatei auf den Server, in dem die aktuelle Version steht (oder eben ein PHP-Script). Diese wird im Programm ausgelesen und mit der programminternen Version verglichen.
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 11.01.09 11:45
Ich würde es so machen: Programm prüft nach, ob Update existiert. Falls ja, das Update-Programm ausführen und sich selbst schliessen. Das Update-Programm führt das Programm nach dem Update wieder aus. Falls ein Update existiert gibt's halt ein kleiner Umweg, dafür ist der normale Fall, wo es kein Update gibt, ohne Umweg.
Das Update-Programm sollte entweder *Updater.exe heissen oder entsprechende Massnahmen treffen, damit unter Vista der UAC Dialog kommt.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 11.01.09 14:12
Um einen Updater zu schreiben ist eigentlich mehr notwendig, als nur eine aktuellere Datei von einem Webserver downzuloaden und diese lokal auch zu ersetzen. Es gab dieses Jahr auf dem 25C3 eine ganze Reihe hrelevanter Angriffe auf sowohl das DNS als auch SSL und TCP, mit denen man einer Anwendung ohne großen Aufwand beliebigen Schadcode "als Update" unterschieben konnte. Also bitte, wenn ihr schon Updater schreibt, dann bitte RICHTIG und bevor irgendwas ausgeführt wird, erstmal überprüfen, was da denn feines runtergeladen wurde, ob das vollkommen echt ist (am besten mit gültigem Code-Signing-Zertifikat, UNTERSCHRIEBENER Prüfsumme (Einfach ein MD5\SHA1\SHA256\SHA512\Whirlpool-Hash reicht nicht, da leicht berechenbar beim Austausch der Datei.
Ferner: Sollte man immer schauen, ob es bereits funktionierende, fertige und geprüfte Lösungen gibt, die die oben genannten Kriterien erfüllen und damit nicht als Malware-Importer missbraucht werden können.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 11.01.09 15:19
Ja ne ist klar. Ich kann ja auch gleich noch bei jedem Update den Autor verständigen, damit dieser vorbeikommt und zuschaut. BenBe, du hast devinitiv zu viel 25C3 geguckt  . Für ein kleines Programm ist das mit dem Aufwand verglichen ziemlich mit Kanonen auf Spatzen schießen. Wer sollte da bitte schön Schadcode einschleusen?
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 11.01.09 15:27
Jemand, der dein Programm nicht mag und lieber deinen Rechner in seinem kleinen Botnetz teilhaben lassen möchte.?
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
bruce185 
      
Beiträge: 283
winXP
D7 Ent
|
Verfasst: So 11.01.09 15:53
Danke euch für die vielen antworten.
Das mit dem Überprüfen nach neue Version und das herunterladen von neue Dateien, funktioniert schon.
Ich habe alles auf meinem Root Server und habe dazu noch eine Textdatei erzeugt, was alles gedownloadet wird, z.B.
downloads.txt
DURL: downloads\test.exe Output: C:\Temp\test.exe
DURL: downloads\test.dll Output: C:\Temp\test.dll
und mein Programm downloadet sie dann auch nacheinander.
Nur wie funktioniert das eigentlich mit der Batch Datei genau?
Also, ich erstelle nach Downloadende eine Batch Datei mit den Informationen, dann lasse ich mein Programm beenden und rufe diese Batch Datei auf, aber wie lasse ich diese Dateien dann von C:\Temp in meinem Ordner Kopieren?
Mein Ordner kann ich ja mit Application.ExeName ermitteln.
Vielen Dank schonmal.
MfG
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 11.01.09 16:20
Ich hab gerade mal bei meinen Programmen nachgeguckt. Wichtig ist noch diese Funktion hier:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| function ANSI2ASCII(AText: String): String; begin {$IFDEF WIN32} CharToOEM(@AText[1], @AText[1]); {$ELSE} AnsiToOEM(@AText[1], @AText[1]); {$ENDIF}
Result := AText; end; |
(Quelle: unbekannt  )
Bei Umlauten in Ordnernamen (z.B. C:\Users\Fabian Gärtner) gibt es sonst ganz große Probleme. Aber jetzt erstmal die wichtigen Parts:
Delphi-Quelltext 1:
| SList.Add('@if exist "' + Tmp + '" del "' + Tmp + '" /F'); |
Erstmal prüfen ob die Exe noch da ist (Tmp = ExtractFilePath(ParamStr(0))). Dann löschen erzwingen (/F).
Delphi-Quelltext 1:
| SList.Add('@copy "C:\Temp\Update.exe" "' + Tmp + '"'); |
Das würde jetzt die Datei an die richtige Stelle kopieren und gleich richtig benennen. Da könnte man noch ein paar Parameter mitgeben (mal copy /? in der Konsole eingeben). Schlussendlich dann noch:
Delphi-Quelltext 1: 2: 3: 4:
| SList.Text := ANSI2ASCII(SList.Text); SList.SaveToFile('TempVerzeichnis\HDUpdater.bat');
ShellExecute(MainForm.Handle, 'open', 'TempVerzeichnis\HDUpdater.bat'), '', '', SW_SHOWNORMAL); |
Ich glaub das sind die wichtigsten Vorgänge. Schön ist natürlich immer noch eine Textausgabe mit @echo für den Anwender, wenns mal wieder länger dauert.
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
bruce185 
      
Beiträge: 283
winXP
D7 Ent
|
Verfasst: So 11.01.09 20:44
Vielen Dank @GTA-Place.
Es klappt sehr gut bis auf eins, und zwar lässt sich das Programm nicht mehr starten nach dem Kopieren, das Fenster bleibt einfach auf ohne fehlermeldung.
Der Pfad zu der .exe Datei stimmt, ich habs überprüft, aber trotzdem lässt sich das Programm nicht starten.
Meine .bat Datei:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| @echo off echo Update... mkdir "entfernt" @if exist "entfernt" del "entfernt" /F @copy "entfernt" "entfernt" mkdir "entfernt" @if exist "entfernt" del "entfernt" /F @copy "entfernt" "entfernt" mkdir "entfernt" @if exist "entfernt" del "entfernt" /F @copy "entfernt" "entfernt" mkdir "entfernt" @if exist "entfernt" del "entfernt" /F @copy "entfernt" "entfernt" Start "C:\Dokumente und Einstellungen\Username\Desktop\Test\Test.exe" |
Alles andere funktioniert bereits, bis auf das starten des Programms.
Danke schonmal.
MfG
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 11.01.09 22:35
Mh... da kann ich jetzt keinen Fehler finden. Vielleicht weiß jemand anders Rat.
Noch ein Tipp: Man sollte das immer so implementieren, dass später auch neue Dateien geupdatet werden können. Also beispielsweise sollte in einer Schleife die Dateinamen aus der Textdatei geupdatet werden. Ich habe den Fehler gemacht, dass ich immer nur die Exe aktualisiert habe. Als später neue Dateien zukamen, konnte keiner Updaten, denn es wurde ja immer nur die Exe aktualisiert und die anderen Dateien ignoriert.
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 12.01.09 00:38
Was ich in der Batchdatei vermisse: Normalerweise sollte diese in einer Schleife die Exe versuchen zu löschen bis das erfolgreich ist (das Programm, das ja die Batch aufruft, also beendet ist). Danach kann man dann die heruntergeladene(n) Datei(en) ans Ziel kopieren (und dabei die alte Exe überschreiben).
|
|
bruce185 
      
Beiträge: 283
winXP
D7 Ent
|
Verfasst: Mo 12.01.09 06:17
Danke euch.
Ich habe mein Problem selber gelöst indem ich die Anführungszeichen zum Pfad entfernt habe, womit ich das Programm starten lasse:
Delphi-Quelltext 1: 2:
| cd C:\Dokumente und Einstellungen\Username\Desktop\Test\ start Test.exe |
Ich wechsel zuerst in dem Pfad und dann lasse ich das Programm starten.
MfG
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mo 12.01.09 08:07
Löschen kann man eine EXE nicht, wenn sie läuft, aber umbenennen.
Wie wäre es mit folgender Strategie?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| Procedure UpdateVersion (aDownloadSource : String); Var sAppPath : String; sAppName, sNewAppName, sOldAppName : String;
Begin sAppPath := ExtractFilePath (ParamStr(0)); sNewAppName := 'NewVersion.EXE'; sAppName := ExtractFileName (ParamStr(0)); sOldAppName := StrReplace (sAppName, '.EXE','_OLD.EXE',[rfCaseInsensitive]); Download(aDownloadSource, sAppPath+sNewAppName); If FileExists (sAppPath+sOldAppName) Then DeleteFile (sAppPath+sOldAppName); RenameFile (ParamStr(0), sOldAppName); RenameFile (sAppPath+sNewAppName, sAppName); End; |
Nun wird nach einem Neustart automatisch die neu heruntergeladene Version gestartet. Die dann alte Version steht als 'xxx_OLD.EXE' weiterhin zur Verfügung. Einen Neustart kann man mit einem kleinen Batch erzwingen ('START '+ParamStr(0)). Ich habs nicht getestet, aber es sollte in etwa so funktionieren.
Wenn das läuft, kannst Du noch BenBEs Sicherheitsüberlegungen mit einbeziehen.
_________________ Na denn, dann. Bis dann, denn.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 12.01.09 12:03
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Do 15.01.09 00:09
Ich denke kaum, dass es bei einem "nicht professionell" geschriebenen/verwendeten Programm viel Sinn macht, das Update wirklich kryptographisch sicher zu gestalten. Der Benutzer hat ja von Anfang an keine Garantie, dass das Programm einwandfrei ist (wenn man schon von so extremen Sicherheitsmassnahmen spricht).
Aber wenn, dann ist das ganze auch nicht so wahnsinnig kompliziert. Im Prinzip reicht es, wenn du das Update-File signierst oder eine Signatur irgendwann im Update-Process separat mitschickst. Mit der Signatur kannst du feststellen, dass die Datei von dir erstellt wurde und von niemandem verändert wurde. Dafür sind digitale Signaturen ja gemacht und gelten als sicher.
Man muss natürlich annehmen können, dass die ursprüngliche (alte) Version und der PC sauber ist und nicht gehackt wurde (der Public Key ist dort ja enthalten). Davon darf man aber glaube ich ausgehen, ansonsten ist dein System ja sowieso schon gehackt und die Sicherheit beim Update nützt dir auch nichts mehr
Was das jetzt mit DNS/TCP/SSL Attacken auf sich hatte, weiss ich jetzt nicht. Und: Ob es selbstsigniert ist oder nicht dürfte für die kryptographische Sicherheit überhaupt keinen Unterschied machen (ausser, dass irgend ein externes Tool, dem du vertraust, im besten Fall was anderes anzeigt. Wenn du willst, dass Windows die Signatur erkennt und deinem Programm vertraut, dann klar, aber darum geht es hier ja nicht)
Die Signaturprüfung kannst du selbst mit existierenden Open-Source Delphi-Komponenten machen. Das ganze natürlich völlig kostenlos. Oder wenn du ein kommerzielles Zertifikat hast wohl auch irgendwie über eine Windows DLL.
|
|
matze
      
Beiträge: 4613
Erhaltene Danke: 24
XP home, prof
Delphi 2009 Prof,
|
Verfasst: Do 15.01.09 11:21
_________________ In the beginning was the word.
And the word was content-type: text/plain.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 15.01.09 12:58
matze hat folgendes geschrieben : | BenBE hat folgendes geschrieben : | Und riskieren, False-Positives bei der Heuristik vom Virenscanner zu erzeugen Yeah!  | Wieso das? Erkläre doch mal bitte! |
Naja, genauso kannst du ja eine fremde Exe umbenennen, die gerade läuft, um eine andere unterzuschieben, die dann beim nächsten Start benutzt wird. Es dürfte allerdings für die Heuristik nicht so einfach sein dies zu erkennen, schließlich handelt es sich erstmal nur um eine normale Dateioperation. Erst wenn das Programm das tatsächlich macht, wäre es gut möglich das zu erkennnen. Ob dann eine Virenwarnung kommt weiß ich nicht. (Bei mir meldet sich die Firewall.)
// EDIT:
matze hat folgendes geschrieben : | alzaimar hat folgendes geschrieben : | Löschen kann man eine EXE nicht, wenn sie läuft, aber umbenennen.  | Seit wann geht das denn? habs grad probiert und bin völlig verblüfft, dass es geht. OK das letzte Mal, dass ich sowas versucht habe war unter ähhh. Win95... |
Das geht auch mit DLLs, so spart man sich den abgesicherten Modus, wenn man eine benutzte Datei ersetzen will. (Bei manchen kann man ja nicht einfach den Prozess beenden.)
|
|
Wii360
      
Beiträge: 18
MS-Dos, Windows 95, Windows Xp (SP 1,2,3)
Php, HTML, Delphi 7 Ent., Delphi 5 Sta., Delphi 3 Sta., Dreamweaver
|
Verfasst: Mi 15.04.09 22:08
Hallo! ICh wollte mich einmsiche, weil ich vor kurzem vor dem gleichen probklem stand und deswegen den Code dazu habe:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| IdFTP1.Get('/DelphiProjects/VersionInfo.txt','Info.txt'); Version.LoadFromFile('Info.txt'); DeleteFile('Info.txt'); if (strtoint(Version[0])>strtoint(VersionInfo)) then begin if (MessageDlg('Deine Version ist nicht mehr aktuell! Du hast die Version "'+VersionsString+'". Version "'+version[1]+'" ist aktuell. Um das Update aufzuspielen drücke bitte [Ja], möchtest du das nicht, oder es manuell machen drücke [Nein].',mtWarning,[mbyes,mbno],0)=mryes) then begin Updated:=true; IdFTP1.Get('/DelphiProjects/Upgrade/Upgrader/Upgrader.exe',Dir+'/Upgrader.exe'); idFTP1.Get('/DelphiProjects/Upgrade/Programmfiles/Teat.exe',Dir+'/_Teat.exe'); end; end; |
Und dann macht der Upgrader.exe folgendes:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.DoUpgrade; var clear:Tstringlist; begin clear:=Tstringlist.create; DeleteFile('Teat.exe'); RenameFile('_Teat.exe','Teat.exe'); clear.SaveToFile('upgraded.dat'); MessageDlg('Teat wurde erfolgreich Upgegraded. Das Programm wird nun gestartet.',mtConfirmation,[mbok],0); WaitMessage; shellexecute(handle,'open',PChar('Teat.exe'),nil,nil,SW_SHOWNORMAL); Application.Terminate; end; |
Und wenn dann Teat.exe bemerkt das die Datei "upgraded.dat" existiret wird Upgrader.exe und upgraded.dat gelöscht. Fertig
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| GetDir(0,dir); if FileExists(dir+'\upgraded.dat') then begin DeleteFile('upgraded.dat'); DeleteFile('Upgrader.exe'); end; |
Achso bei mir Funktioniert das alles über meinen eigenen FTP-Server (Da ich Auch websites programmiere hab ich so einen!)
MFG Wii360
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Mi 15.04.09 22:13
Dann hast du aber in deinem Programm die Logindaten hinterlegt und damit hätte so ziemlich jeder Zugriff auf deinen FTP-Server, gewollt?
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
|