unit AutoUpdateUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP, StdCtrls;
type
TAutoUpdateForm =
class(TForm)
AutoUpdateProgress: TProgressBar;
HTTPAutoUpdate: TIdHTTP;
SpeedStatus: TLabel;
AutoUpdateStatus: TLabel;
procedure HTTPAutoUpdateWorkBegin(ASender: TObject; AWorkMode: TWorkMode;
AWorkCountMax: Int64);
procedure HTTPAutoUpdateWork(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Int64);
procedure DoAutoUpdate(fileName:
String);
private
{ Private-Deklarationen }
FTime: Longword;
//Beide Variablen werden für die kb/sec anzeige gebraucht
FBytes: Longword;
// --"--
public
{ Public-Deklarationen }
end;
var
AutoUpdateForm: TAutoUpdateForm;
const
cFileSplitSize : Int64 = 40*1024;
//40 KB größe stücke wird die Datei zerhackt
implementation
{$R *.dfm}
function GetSizeName(
const Size : int64):
String;
begin
Result := '
Fehler';
if Size = -1
then exit;
if Size < 1024
then
begin
Result := inttostr(Size)+'
Byte';
exit;
end;
if (1024 <= Size)
and (Size < 1048576)
then
begin
Result := floattostr((round((Size/1024)*100))/100)+'
KB';
exit;
end;
if (1048576 <= Size)
and (Size < 1099511627776)
then
begin
Result := floattostr((round((Size/1048576)*100))/100)+'
MB';
exit;
end;
if Size > 1099511627776
then
begin
Result := floattostr((round((Size/1099511627776)*100))/100)+'
GB';
end;
end;
procedure TAutoUpdateForm.DoAutoUpdate(fileName:
String);
var
BytesKopiert, BytesInsgesamt : int64;
lStream: TFileStream;
RemotePath:
String;
begin
RemotePath:='
http://localhost/';
self.Show;
self.BringToFront;
//Initialiesieren
AutoUpdateStatus.Caption := '
';
BytesKopiert := 0;
AutoUpdateProgress.Position := 0;
//In edit 1 steht die downzuladene Datei (z.b. [url]http://www.server.com/datei.dat[/url])
AutoUpdateStatus.Caption := '
Prüfe Header';
// Durch die zwei nächsten Befehle wird die Größe ermittelt und ihn der Variable BytesInsgesamt abgespeichert
HTTPAutoUpdate.Head(RemotePath+fileName);
BytesInsgesamt := HTTPAutoUpdate.Response.ContentLength;
//Wenn die Indy Komponente -1 zurückgibt dann bedeutet es des der die Dateigröße nicht zu verfügung
//stellt uns somit kann die Datei ganz normall heruntergeladen werden (ohne Fortschrittsanzeige)
if BytesInsgesamt = -1
then
begin
AutoUpdateStatus.Caption := '
Normalles herunterladen';
AutoUpdateStatus.Caption := '
Erstelle Datei';
//In Edit 2 steht welche Datei (z.b. C:\datei.dat)
//Datei erstellen
lStream:=TFileStream.Create(ExtractFilePath(Application.ExeName)+fileName, fmCreate
or fmShareDenyNone);
try
//und "normal" herunterladen
HTTPAutoUpdate.Get(RemotePath+fileName, lStream);
finally
if Assigned(lStream)
then lStream.Free;
//FileStream freigeben wenn gesetzt
end;
//Alles auf fertig stellen
AutoUpdateStatus.Caption := '
Fertig';
SpeedStatus.caption := '
Fertig';
exit;
end;
//Also wenn wir hier angelangt sind dann bedeutet es der Server hat uns die Dateigröße zur Verfügung gestellt.
AutoUpdateProgress.Max := BytesInsgesamt;
AutoUpdateStatus.Caption := '
Erstelle Datei';
//In Edit 2 steht welche Datei (z.b. C:\datei.dat)
//Datei erstellen
lStream:=TFileStream.Create(ExtractFilePath(Application.ExeName)+fileName, fmCreate
or fmShareDenyNone);
lStream.Position := 0;
try
repeat
// Damit sich das Programm nicht aufhängt
Application.ProcessMessages;
//Hier wird gebrüft ob die restlichen Bytes größer sind als cFileSplitSize
if (BytesInsgesamt-BytesKopiert) > cFileSplitSize
then
begin
//Hier wird einmal die cFileSplitSize eingestellt
HTTPAutoUpdate.Request.Range := Format('
%d-%d', [BytesKopiert, (BytesKopiert+cFileSplitSize-1)]);
end
else HTTPAutoUpdate.Request.Range := Format('
%d-', [BytesKopiert]);
Application.ProcessMessages;
//Den eingesttelten Teil herunterladen und ihn die Datei speichern
HTTPAutoUpdate.Get(RemotePath+fileName, lStream);
//Progress und Status aktualliesieren
AutoUpdateProgress.Position := BytesKopiert;
AutoUpdateStatus.Caption := GetSizeName(BytesKopiert)+'
/'+GetSizeName(BytesInsgesamt);
//BytesKopiert weiter setzen
BytesKopiert := BytesKopiert+cFileSplitSize;
until (BytesKopiert >= BytesInsgesamt);
//Schleife beenden wenn datei fertig
finally
if Assigned(lStream)
then lStream.Free;
//FileStream freigeben wenn gesetzt
HTTPAutoUpdate.Request.Range := '
';
//Verhindert das die nächste Anfrage in einem 206 Fehler endet
end;
//Alles auf fertig stellen
AutoUpdateStatus.Caption := '
Fertig';
SpeedStatus.caption := '
Fertig';
AutoUpdateProgress.Position := 100;
end;
procedure TAutoUpdateForm.HTTPAutoUpdateWork(ASender: TObject;
AWorkMode: TWorkMode; AWorkCount: Int64);
begin
if not((GetTickCount - FTime) <= 0)
then
begin
try
SpeedStatus.caption := Format('
%.2f KB/s', [(AWorkCount - FBytes) / (GetTickCount - FTime)]);
except
end;
end;
FTime := GetTickCount;
FBytes := AWorkCount;
Application.ProcessMessages;
end;
procedure TAutoUpdateForm.HTTPAutoUpdateWorkBegin(ASender: TObject;
AWorkMode: TWorkMode; AWorkCountMax: Int64);
begin
FTime := GetTickCount;
FBytes := 0;
Application.ProcessMessages;
end;
end.