![]() |
Updater funktion im Thread
Hallo Zusammen,
Ich habe mir einen Updater nach diesem Tutorial nachgebaut: ![]() Jetzt möchte ich gerne den Updater in mein Hauptprogramm einfügen, ohne den Willkommens und Installation Erfolgreich Tab und ohne das ich erst auf Installation Starten klicken muss. Lasse ich die sachen nun einfach weg und setze die Progressbars und Anzeigen des Updates Tabs auf eine leere Form, dann hängt sich das Programm auf und zeigt sich erst nach dem Erfolgreichen Update. mein Problem ist jetzt, versuche ich die funktion in ein Thread zu setzen funktioniert nichts. Dabei muss ich aber auch sagen, das ich den Aufbau des Threads nicht wirklich verstehe. Vielleicht gibt es hier jemand nettes, der mein Problem bzw. vorhaben anhand meiner unten beigefügten Unit erkennt und mir es vielleicht beheben könnte.
Delphi-Quellcode:
unit UpdaterETS;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP, ShellAPI; type Tupdater = class(TForm) FortschrittNow: TLabel; FortschrittGesamt: TLabel; ProgressAktuell: TProgressBar; ProgressGesamt: TProgressBar; FileNumber: TLabel; DownSpeed: TLabel; FTP: TIdFTP; procedure FTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); procedure FTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); procedure FormCreate(Sender: TObject); private //procedure Connect; //procedure Disconnect; public { Public declarations } end; type ThUpdater = class(TThread) FortschrittNow: TLabel; FortschrittGesamt: TLabel; ProgressAktuell: TProgressBar; ProgressGesamt: TProgressBar; FileNumber: TLabel; DownSpeed: TLabel; FTP: TIdFTP; procedure UpdateFunc; private procedure Connect; procedure Disconnect; { Private-Deklarationen } protected procedure Execute; override; end; var updater: Tupdater; versionAK, versionNeu: string; StartTime: TDateTime; Size: Int64; CurrentFile, FileCount: Integer; UpdatingActive: Boolean = false; implementation {$R *.dfm} uses UnitConnection; function DeleteFileDir(const AFile: string): Boolean; var SH: SHFILEOPSTRUCT; begin ZeroMemory(@SH,SizeOf(SH)); with sh do begin WND:=Application.Handle; wFunc:=FO_DELETE; pFrom:=PChar(AFile+#0); fFlags:=FOF_SILENT or FOF_NOCONFIRMATION; end; Result:=ShFileOperation(sh)=0; end; procedure Thupdater.Connect; begin FTP.Host:=ConHost; FTP.Username:=ConUser; FTP.Password:=ConPass; FTP.Connect; FTP.ChangeDir(ConDir); end; procedure Thupdater.Disconnect; begin FTP.Disconnect; end; procedure Tupdater.FTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); begin StartTime:=Now; if AWorkCountMax>0 then begin ProgressAktuell.Max:=AWorkCountMax; end else ProgressAktuell.Max:=Size; end; procedure ThUpdater.UpdateFunc; var Update, Befehl: tstringlist; I: Integer; begin CurrentFile:= i; Size:= FTP.Size(Befehl[1]); FTP.Get(Befehl[1],Befehl[2],True); ProgressGesamt.Position:=ProgressGesamt.Position+1; end; procedure ThUpdater.Execute; var Update, Befehl: tstringlist; I: Integer; begin Connect; Update:=tstringlist.Create; Befehl:=tstringlist.Create; CreateDir('tmp'); FTP.Get('updates.ini','tmp\updates.ini',true); Update.LoadFromFile('version.txt'); versionAK:=Update[0]; Update.Clear; Update.LoadFromFile('tmp\updates.ini'); versionNeu:=Update[0]; try //----------------------------------------------------------------------------------------- //FileCount bestimmen //----------------------------------------------------------------------------------------- for i := Update.Count - 1 downto 0 do begin Befehl.Clear; ExtractStrings([';'],[],PChar(Update[i]),Befehl); if Befehl[0]='get' then inc(FileCount); end; //----------------------------------------------------------------------------------------- UpdatingActive:=True; for i := Update.Count - 1 downto 0 do begin Befehl.Clear; ExtractStrings([';'],[],PChar(Update[i]),Befehl); if Befehl[0]='dir' then CreateDir(Befehl[1]); if Befehl[0]='del' then DeleteFileDir(Befehl[1]); if Befehl[0]='get' then begin CurrentFile:= i; Size:= FTP.Size(Befehl[1]); FTP.Get(Befehl[1],Befehl[2],True); ProgressGesamt.Position:=ProgressGesamt.Position+1; end; end; finally UpdatingActive:=False; Update.Free; Befehl.Free; DeleteFileDir('tmp'); Disconnect; end; end; procedure Tupdater.FormCreate(Sender: TObject); var myTh: ThUpdater; begin myTh:= Thupdater.Create(True); myTh.Resume; end; procedure Tupdater.FTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); var Speed: String; TotalTime: TDateTime; H,M,Sec,MS: Word; DLTime: Double; begin if UpdatingActive=True then begin TotalTime:= Now-StartTime; DecodeTime(TotalTime,H,M,Sec,MS); Sec:=Sec+M*60+H*3600; DLTime:=Sec+MS/1000; if DLTime>0 then Speed:= FormatFloat('0.00 KB/s',(AWorkCount/1024)/DLTime); FileNumber.Caption:='Datei: ' +IntToStr(CurrentFile)+ ' von ' +IntToStr(FileCount); DownSpeed.Caption:= 'Geschwindigkeit: '+Speed; ProgressAktuell.Position:=AWorkCount; end; end; end. Gruss Jappa |
AW: Updater funktion im Thread
Zitat:
Ansonsten: Zugriffe auf visuelle Komponenten (Label, ProgressBar usw) aus einem Thread heraus müssen immer Synchronisiert werden. Beispiel
Delphi-Quellcode:
Es kann auch ohne Synchronize funktionieren, geht aber irgendwann auf irgendeinem System in die Hose und verursacht Probleme.
Synchronize(
procedure begin // hier auf die Komponente zugreifen end); |
AW: Updater funktion im Thread
Zitat:
Hab es als Update.rar am Beitragsende angehängt :D Gruss Jappa |
AW: Updater funktion im Thread
Ich bin mir nicht sicher. Aber ich glaube viele werden da gar nicht erst draufklicken.
Da könnte ja was mit mod_rewrite oder so dahinterstecken :P |
AW: Updater funktion im Thread
Zitat:
Ok, verständlich, dann werde ich es als code Zitieren :D EDIT: Code steht oben, mit Synchronize hatte ich es gestern schon versucht, aber leider klappte es auch nicht :/ |
AW: Updater funktion im Thread
Wo sind die Verbindungsdaten gespeichert?
Ich frage deshalb, weil wenn die im Programm selber liegen, dann kannst du alles was mit FTP zu tun hat direkt rausschmeißen oder dein Passwort direkt im Klatext in die Form-Caption schreiben. Ein Tutorial über so einen Updater nachzubauen ist meiner Meinung nach leichtsinnig. |
AW: Updater funktion im Thread
Die Connect-Daten sind in einer UnitConnection.pas gespeichert und werden in die Hauptform mit Uses UnitConnection; implementiert.
Delphi-Quellcode:
unit UnitConnection;
interface const ConDir='xxxx'; ConHost='xxxxx'; ConUser='xxxx'; ConPass='xxxxx'; implementation end. |
AW: Updater funktion im Thread
Ich kann dir nicht empfehlen das so zu machen wie im Video gezeigt wird.
Ich sehe da nur Probleme: - Benutzerkonten Steuerung - keine Schreibrechte - FTP geht schlecht durch Firewalls - Umgehung von "Installern" - Falsche Versionsnummern in der Systemsteuerung unter Software - evtl. große Sicherheitslücken Bei den Delphi Tagen 2010 und im Entwickler Magazin hatte ich eine alternative gezeigt: ![]() - MSI als Setup - MSP für kleine Downloads wenn Patch - BITS für Download weil in Firewall freigeschaltet - HTTPS als Download Protokoll |
AW: Updater funktion im Thread
Zitat:
Dieses Tutorial sollte vom Netz genommen werden. |
AW: Updater funktion im Thread
Zitat:
Nimm das bitte als positive Kritik wahr und fühl dich nicht angegriffen. :zwinker: |
AW: Updater funktion im Thread
Vielen Dank erstmal für die schnellen Antworten.
Ich habe mir jetzt mal den Updater von generic runtergeladen, was mir nun nur auffällt, sämtliche Jwa Dateien werden nicht gefunden, muss ich das packet noch installieren? Benutze die Delphi 10.2 Tokyo Architect Version. Gruss Jappa |
AW: Updater funktion im Thread
Zitat:
![]() Wenn du bei den Foren-Tagen bist, kannst du mich auch gerne ausfragen. ;-) |
AW: Updater funktion im Thread
Zitat:
|
AW: Updater funktion im Thread
Zitat:
Also ich speichere meine Daten generell in einer Ini- bzw. XML-Datei verschlüsselt ab und weiß was es für Probleme geben kann wenn man sie im SourceCode ablegt. Es wäre aber eben generell schön, wenn jemand eine Begründung abgeben würde weshalb man etwas besser nicht machen sollte oder derjenige es blöd findet wie etwas umgesetzt ist. :| |
AW: Updater funktion im Thread
Besser machen ist schwierig, deswegen hab eich dazu nichts gesagt.
|
AW: Updater funktion im Thread
Zitat:
Zitat:
Aber andere Frage, wenn ich den Updater jetzt auf mein Programm anpasse, muss ich ihn dann noch in ein Thread packen? oder kann ich ihn mit gewissen änderungen in meine Form einbauen? Das Hauptprogramm soll später hauptteils aus DLLs bestehen, die dann nach und nach geupdatet werden sollen. |
AW: Updater funktion im Thread
Liste der Anhänge anzeigen (Anzahl: 1)
Diese Thread-Sachen ist schwieriger zu programmieren. Ich hab 20 Jahre kaum Threads gebraucht. Für diese Dinge sehe ich die Threads nicht.
Wenn du den BITS verwendest, dann blockiert deine Anwendung nicht. Threads nutzt man zu parallelisieren von Aufgaben oder um sie im Hintergrund zu machen (ohne das die Anwendung blockiert). Mit Threads heißt das Gedanken machen über Synchronisierung, Deadlocks usw. Tipp: Lass die Finger von. Da du eh ein Setup brauchst für die Erstinstallation, dann brauchst du auch für jede nachfolgende Version deiner Software ein ganzes Setup. Tipp: Finger weg von einzelnen Datei Aktualisierungen Erzeuge MSI Dateien, wenn du wirklich ein Patch liefern willst, z.B. für kleinere Downloads - erzeuge eine MSP. Tipp: WIX-Toolset ![]() Ich hab hier noch die Folien, allerdings sind da nur Stichwort drauf - ohne Moderation wenig benutzbar. |
AW: Updater funktion im Thread
Zitat:
Zitat:
Zitat:
Stehe halt jetzt noch vor dem Problem JEDI zu installieren, irgendwie bin ich zu blöd für, finde aber auch in google nichts... oooder ich suche falsch danach ^^ Gruss Jappa |
AW: Updater funktion im Thread
Zitat:
|
AW: Updater funktion im Thread
ihr mach euch um Dinge Gedanken, wo TMS für wenig Euros das seit Jahren incl. UpdateBuilder recht stabil incl. UAC gelöst hat.
![]() Bei der "eigenen Updateprüfung" empfehle ich ein asymetrisches Verschlüsselungs Verfahren (z.B. RSA), da kann man im Programm den PublicKey ruhig mit rein linken. Nur man selbst kann per PrivateKey die UpdateFiles so verschlüsseln, das es das eigene Programm dann auch dekodieren kann... Das ist dann quasi zugleich eine sehr sichere Authentifizierung der Herkunft, weil auch böse Hacker mit dem PublicKey aus der EXE noch lange keinen PrivateKey zur Erstellung eines modifizierten/bösen Updates haben. Klar kann man alles selbst machen, aber es gibt wohl niemanden der das incl UpdateBuilder und Support in weniger Zeit wie ihm 50Eur wert sind mindestens so gut hin bekommen kann;) |
AW: Updater funktion im Thread
Zitat:
Wäre das hier nicht auch eine Idee oder ist das zu unsicher? - Client fragt Updatedateien vom Server an - ein Script auf dem Server antwortet, dass Updates vorhanden sind oder nicht - sind welche vorhanden, entschlüsselt das Script, welches auf dem Server liegt, die Dateien die auch auf dem Server liegen und schickt sie dann los Oder habe ich gerade einen Knoten im Hirn? |
AW: Updater funktion im Thread
Du hast Konten im Hirn;)
..."sind welche vorhanden, entschlüsselt das Script, welches auf dem Server liegt, die Dateien die auch auf dem Server liegen und schickt sie dann los".. => NIEMALS entschlüsselt der Server etwas vor der Übertragung!!! -> Eventuell verschlüsselt es der Server mit dem Key des Systems und übeträgt die Daten dann so, das NUR der Client sie entschlüsseln kann, würde ich aber NICHT so machen, denn dann lägen SystemKeys auf dem Server... NÖ, man verschlüsselt die ClientUpdates in eigener sicherer Umgebung selbst und lädt die verschlüsselten Dateien auf den Server hoch. -> Anfragende Clients bekommen so der so stets nur verschlüsselte Dateien per Download, welche auch nur sie selbst entschlüsseln können. Hacker nützt es hier nix bei Server oder Client das Programm, den Speicher oder die Datenübertragung zu analysieren/manipulieren. ->eine "Verschlüsselung" mit dem privaten Schlüssel stellt eine Signatur dar, da jeder(Client), der im Besitz des öffentlichen Schlüssels ist(im Programcode oder gehackt), die Nachricht entschlüsseln kann. Somit schützt man so nicht direkt die Daten gegen fremdes dekodieren, sondern man beweist dem Empfänger(also dem ClientProgramm), dass man selbst sie herausgegeben hat und es ein echtes Update ist(s. Authentitzität und Integrität). |
AW: Updater funktion im Thread
Das mit dem privaten und öffentlichen Schlüssel kapiere ich nicht.
Wenn der private sowie der öffentliche Schlüssel entschlüsseln können kann man doch auch gleich einen einzigen Schlüssel nehmen. Am Ende liegt ja trotzdem ein Schlüssel in der Exe. |
AW: Updater funktion im Thread
Bei asymetrischen Verfahren wie RSA gibt es immer ein SchlüsselPaar...
- einen PrivateKEY und einen zugehörigen PublicKEY - der PublicKey ist öffentlich, DARF UND SOLL also verteilt werden... wie z.B. hier in die EXE einkompiliert werden - es gilt erstens, mit dem Key welchen man zu Verschlüsselung benutzt hat, kann man die Daten nicht mehr dekodieren (=> ASYMETRISCHES VERFAHREN) - es gilt zweitens: was mit dem PublicKEY "verschlüsselt" wird, kann nur mit dem "PrivateKEY" entschlüsselt werden - es gilt dritens: was mit dem PrivateKEY "verschlüsselt" wird, kann man mit dem "PublicKEY" dekodieren und so die Herkunft prüfen, denn nur der Besitzer des PrivateKEY konnte das so erstellen... deshalb nennt sich dieser Weg auch "signieren" und nicht verschlüsseln Der Trick an RSA ist ja, das man im unsicherem Gebiet, also im ClientBereich oder bei der Übertragung (Server,INET,..) NIEMALS den PrivateKey herausgeben muss und trotzdem per PublicKey sowohl sichere Verschlüsselung aus auch sichere Herkunftsprüfung(im Sinne von Identifikation und Authentifizierung) möglich ist. Die Besonderheiten Asym. Cryptoverfahren und die sich daraus ergebende jeweils sinnvolle Anwendung der Keys bzw. Methoden zum PrivatKeyManagement sprengen den Rahmen dieses Threads, hier geht es um eine sinnvoll Absicherung von Updates, und da bietet es sich an NICHTS mit geheimen Schlüsseln oder Passwörtern im Clientprogramm zu machen. Genau da ist der PublicKey der Ideale KEY. So kann sogar wenn der Client zum Server damit echt verschlüsselte Daten schicken, die dann im Server undekodierbar lagern, bis man sie selbst von dort abholt und in eigener sicherer Umgebung dann mit dem PrivateKey dekodiert... so gibt es nie Datenschutzprobleme auf dem Server, denn dort liegen stets nur wertlose verschlüsselte Binärdateien und keinerlei Keys. |
AW: Updater funktion im Thread
Also kurz gefasst:
Dateien auf dem Server mit dem privateKey kodieren und den publicKey in die Exe aufnehmen, damit diese die runtergeladenen Dateien dekodieren kann? Wo bekommt man irgendwas mit RSA denn her? DEC scheint ja keine zwei Keys zu unterstützen ![]() Ich hätte hier zwar was, aber das ist glaube ich nur für Strings ![]() |
AW: Updater funktion im Thread
..."Dateien auf dem Server mit dem privateKey kodiert speichern und den publicKey in die Exe aufnehmen, damit diese die runtergeladenen Dateien dekodieren kann"...
=> ja genau so:) ![]() sorry, auch bei sowas ist mir die Suche nach Freewarevarianten zu lässtig, wenn es für unter 100Eur was gibt was gepflegt wird und gut mit Support noch gut dokumentiert ist |
AW: Updater funktion im Thread
Zu teuer ;) Außerdem halte ich von TMS nix.
Was ist denn davon zu halten? ![]() |
AW: Updater funktion im Thread
RSA steht bei LockBox3 mit dabei... und genau da ist jetzt der Unterschied... bei an TMS schreibste denen was du vor hast und die antworten dir mit welchen ihrer Komponenten es wie geht:)
Jedem das seine, ich finde DevArt und TMS haben angemessene Preise und überleben so trotz der Freewarealternativen ja auch. Und TMS+UniDAC machen günstiger für DB und Cloud aus einem Delphi-Pro mehr, wie einem ein Delphi-Ent für teuer Geld bietet, sogesehen ist TMS da sogar "billig", zumal Source und 2Jahre VollSupport immer dabei:) Ich habe nix gegen Freeware und Leute die diese machen oder die es nutzen, nur die Suche nach XY nervt im Delphibereich, weil es im INet dazu kaum eine breite offene Sourcebasis gibt. Da stehe ich dann dazu, das ich privat bei 100€ max. 5h meiner Zeit investieren würde, denn 20€/h ist mir meine Freizeit wert. Geschäftlich würde ich bei 100€ Kosten die Grenze schon bei nur 3h setzen. |
AW: Updater funktion im Thread
Zitat:
|
AW: Updater funktion im Thread
Knoten im Hirn. Wenn jemand was an dich schickt nimmt er den Public Key. Das kannst nur du mit deinem Private Key entschlüsseln und niemand sonst.
Verschickst du, nimmst du logischerweise den Private Key. Das kann der Empfänger mit deinem Public Key entschlüsseln. |
AW: Updater funktion im Thread
wenn man den PrivateKey zum "verschlüsseln" nimmt, bezeichnet man das ja auch besser gleich als SIGNIEREN und nicht mehr als "verschlüsseln", dass verhindert ev. ein paar Knoten im Hirn.. schafft aber neue weil man wissen muss wo der sicherheits technische Unterschied ist:
- einmal kann nur der Empfänger es dekodieren und weiß so, das es "nur für ihn ist" (das mach Sinn für vertrauliche Daten die nur für EINEN Empfänger bestimmt sind) - andererseits kann jeder es per PublicKey dekodieren und jeder weiß dabei "von wem es ist" (das mach Sinn für verlässliche Updates aus sicherer Quelle) => es gibt dann aber noch zig mehrstufige Kombinationen daraus, wo dann meist noch temporäre symetrische SessionKeys erzeugt und sicher ausgetauscht werden... kann man auch beim Updateprozess mit vorsehen, wenn es um Austausch/Freischaltung von Lizenzinfos an/für genau einen Client geht, aber das sprengt die einfache Threadfrage, wie man "sicher" ein Update an mehrere Clients verteilt. |
AW: Updater funktion im Thread
Signieren und verschlüsseln ist zweierlei, aber es macht wenig Sinn, etwas mit meinem privaten Schlüssel zu verschlüsseln. Da ist es üblicher, etwas zu signieren.
Signieren ist eine Prüfsumme bilden und diese mit dem privaten Schlüssel verschlüsseln. Diese Prüfsumme kann jeder mit dem öffentlichen Schlüssel verifizieren. Beim Signieren wird aber der Inhalt nicht verändert und schon gar nicht unles- bzw. unnutzbar. Beim Verschlüsseln wird der Inhalt genommen - oft komprimiert - und mit dem passenden Schlüssel verschlüsselt. Der passende Schlüssel ist bei Verschlüsseln und Signieren: a) Wenn ich den Inhalt nur einem Zugänglich machen will: Der private Schlüssel des Gegenüber b) Wenn ich den Inhalt öffentlich machen will: Mein Privater Schlüssel Private Schlüssel gehen nie übers Netz oder an jemanden Dritten. Sonst sind sie nicht mehr privat! |
AW: Updater funktion im Thread
Ist es möglich wenn man einen private und public key hat einen String mit dem private Key durch ein PHP Script verschlüsseln zu lassen und in Delphi mit dem public Key entschlüsseln zu lassen?
|
AW: Updater funktion im Thread
..."Ist es möglich wenn man einen private und public key hat einen String mit dem private Key durch ein PHP Script verschlüsseln zu lassen und in Delphi mit dem public Key entschlüsseln zu lassen?"...
-> nochmal: mit PrivateKey "verschlüsseln" nennt man "signieren" und mit PublicKey "entschlüsseln" nennt man "Signatur prüfen"! -> ja es wäre also möglich (wenn man auf dem Server ein "passendes" PHP Script samt des "PrivateKeys" hat) -> ich würde nicht tun, weil ich "PrivateKeys" für dort deplaziert und für unsicher halte... man nutze den Server besser passiv als reines "Dateilager"... notfalls implementier man lieber per PHP einen REST BackendCall auf einen eigenen lokalen "REST/AppServer" -> man nehme PRIVATEKEY bitte WÖRTLICH!!! ein solcher Key verläßt NIEMALS das eigene Haus -> wenn ein Server etwas speziell für einen Client verschlüsseln soll, dann macht er das sinnvollerweise per SessionKeyVerfahren |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz