Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Updater funktion im Thread (https://www.delphipraxis.net/193903-updater-funktion-im-thread.html)

Jappa 21. Sep 2017 13:05

Updater funktion im Thread
 
Hallo Zusammen,

Ich habe mir einen Updater nach diesem Tutorial nachgebaut: https://www.youtube.com/watch?v=bBBH1MT89dg .

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

Glados 21. Sep 2017 13:12

AW: Updater funktion im Thread
 
Zitat:

mein Problem ist jetzt, versuche ich die funktion in ein Thread zu setzen funktioniert nichts.
Zeig mal deinen Code. Was genau machst du?

Ansonsten: Zugriffe auf visuelle Komponenten (Label, ProgressBar usw) aus einem Thread heraus müssen immer Synchronisiert werden.
Beispiel
Delphi-Quellcode:
Synchronize(
 procedure
  begin
   // hier auf die Komponente zugreifen
  end);
Es kann auch ohne Synchronize funktionieren, geht aber irgendwann auf irgendeinem System in die Hose und verursacht Probleme.

Jappa 21. Sep 2017 13:17

AW: Updater funktion im Thread
 
Zitat:

Zitat von Glados (Beitrag 1381772)
Zitat:

mein Problem ist jetzt, versuche ich die funktion in ein Thread zu setzen funktioniert nichts.
Zeig mal deinen Code. Was genau machst du?


Hab es als Update.rar am Beitragsende angehängt :D


Gruss Jappa

Glados 21. Sep 2017 13:22

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

Jappa 21. Sep 2017 13:25

AW: Updater funktion im Thread
 
Zitat:

Zitat von Glados (Beitrag 1381777)
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


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 :/

Glados 21. Sep 2017 13:27

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.

Jappa 21. Sep 2017 13:33

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.

generic 21. Sep 2017 13:54

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:
https://entwickler.de/wp-content/upl...t_updates1.zip

- MSI als Setup
- MSP für kleine Downloads wenn Patch
- BITS für Download weil in Firewall freigeschaltet
- HTTPS als Download Protokoll

Glados 21. Sep 2017 14:33

AW: Updater funktion im Thread
 
Zitat:

Die Connect-Daten sind in einer UnitConnection.pas gespeichert und werden in die Hauptform mit Uses UnitConnection; implementiert.
Ganz schlechte Idee.
Dieses Tutorial sollte vom Netz genommen werden.

Aviator 21. Sep 2017 15:21

AW: Updater funktion im Thread
 
Zitat:

Zitat von Glados (Beitrag 1381787)
Zitat:

Die Connect-Daten sind in einer UnitConnection.pas gespeichert und werden in die Hauptform mit Uses UnitConnection; implementiert.
Ganz schlechte Idee.
Dieses Tutorial sollte vom Netz genommen werden.

Es wäre schön wenn du, statt nur zu "fluchen", begründen würdest wieso du das denkst und eine Möglichkeit aufzeigst (mit SourceCode und den zugehörigen Res-, Config-Files o.ä.) wie es besser gemacht werden könnte. Alleine schon deshalb, damit andere die diesen Thread später mal lesen nicht nach unten scrollen und denken, dass ein besserer Lösungsvorschlag auch hätte gepostet werden können wenn man schon darüber meckert.

Nimm das bitte als positive Kritik wahr und fühl dich nicht angegriffen. :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:55 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz