Autor Beitrag
dYnAm1c
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 27.04.11 00:04 
Hi,
bin gerade auf das Forum hier gestoßen und suche Hilfe für meinen kleinen "Update" -Code, welcher mit einer Ini Datei arbeitet welche sich auf einem Server befindet.
Das Tool soll lädt die "config.ini" vom Server runterladen, danach fängt allerdings der Fehler an. Ich möchte das die Version die in der Ini Datei steht ausgelesen wird und in "Listbox2.Items" geschrieben wird, allerdings scheint er diesen Schritt zu überspringen und sagt einfach sofort das die Version "up2date" ist. Der Code ist leider nicht sehr aufgeräumt, ist eins meiner etwas größeren Projekte ;). Hier die nötige Source:

Update Button:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
procedure TForm2.UpdateBtnClick(Sender: TObject);
var
  stream: TFileStream;
  ini: TiniFile;
  Version: Extended;
begin
if (rdy = 0then
begin
stream := TFileStream.Create('config.ini', fmCreate);
HTTP1.Get('http://raidtest.ra.funpic.de/config.ini', stream);
end;

if (rdy = 1then
begin
ini := TiniFile.Create(ExtractFilePath(ParamStr(0))+ 'config.ini');
ini.ReadSectionValues('VersionCL', Listbox2.Items);
ini.Free;
end;
if (Listbox1.ItemIndex = Listbox2.ItemIndex) then
begin
Application.MessageBox('Your Client is already up 2 date!''Up 2 Date', MB_ICONINFORMATION or MB_OK);
Exit;
end
else
if (Listbox1.ItemIndex <> Listbox2.ItemIndex) then
begin
stream := TFileStream.Create('Chat Client 1.5.exe', fmCreate);
HTTP2.Get('http://raidtest.ra.funpic.de/Chat_Client_1.5.exe');
end;
end;


Die WorkEnd Prozedur vom Ini Download:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm2.HTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
Application.MessageBox('Config File Downloaded!''Config Download', MB_ICONINFORMATION or MB_OK);
Stream.Free;
rdy := 1;
UpdateBtn.Click;
end;


Zuletzt bearbeitet von dYnAm1c am Mi 27.04.11 16:27, insgesamt 1-mal bearbeitet
Thom
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 70
Erhaltene Danke: 5


Delphi 10 Seattle Prof.
BeitragVerfasst: Mi 27.04.11 01:19 
Da sind einige Fehler im Quelltext.
Ich mach's um diese Uhrzeit kurz und biete eine funktionierende Variante an:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TForm1.UpdateBtnClick(Sender: TObject);
var
  Stream: TMemoryStream;
  Ini: TStringList;
  Version: Extended;
  OldDecimalSeparator: Char;
begin
  Stream:=TMemoryStream.Create;
  try
    HTTP1.Get('http://raidtest.ra.funpic.de/config.ini',Stream);
    //Weshalb der Umweg über eine INI-Datei auf der Festplatte?
    //Eine String-Liste tut's auch:
    Ini:=TStringList.Create;
    try
      Stream.Seek(0,soFromBeginning);
      Ini.LoadFromStream(Stream);
      OldDecimalSeparator:={FormatSettings.}DecimalSeparator;
      {FormatSettings.}DecimalSeparator:='.'//wäre überflüssig, wenn gleich ein Komma genutzt würde
      Version:=StrToFloatDef(Ini.Values['VersionCL'],0);
      {FormatSettings.}DecimalSeparator:=OldDecimalSeparator;
    finally
      Ini.Free;
    end;
    if Version<>AktuelleVersion then
    begin
      Stream.Clear;  //Stream wird auch zum Download der Datei benutzt
      //Wozu eine zweite HTTP-Komponente? Dazu kann auch die erste benutzt werden:
      HTTP1.Get('http://raidtest.ra.funpic.de/Chat_Client_1.5.exe',Stream);
      Stream.SaveToFile('Chat Client 1.5.exe'); //hier könnte noch ein SaveDialog eingefügt werden oder zumindest ein "ordentlicher" Pfad
    end else ShowMessage('Alles OK');
  finally
    Stream.Free;
  end;
end;
dYnAm1c Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 27.04.11 14:13 
Hi,

deine Variante funktioniert wunderbar, würde sie aber auch gerne verstehen :p
könntest du vielleicht folgende Zeilen erklären und wofür sie seien sollen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Stream.Seek(0,soFromBeginning);

OldDecimalSeparator := DecimalSeparator;

DecimalSeparator:='.';

Version:=StrToFloatDef(Ini.Values['VersionCL'],0); // StrToFloatDef kenn ich gar nicht :D


//und was ist der unterschied zwischen TMemoryStream und TFileStream?
//kann man die Datei mit ersterem direkt im Internet aufrufen?



mfg
Thom
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 70
Erhaltene Danke: 5


Delphi 10 Seattle Prof.
BeitragVerfasst: Mi 27.04.11 15:01 
ausblenden Delphi-Quelltext
1:
2:
Stream.Seek(0,soFromBeginning);
//...

Jeder Stream hat einen "Zeiger" auf die aktuelle Position innerhalb der Daten: TStream.Position. Nach dem Schreiben in einen Stream beinhaltet TStream.Position meist den Wert von TStream.Size: Der "Zeiger" zeigt also auf das Ende des Streams.
Wird aus einem Stream gelesen, verwenden viele Komponenten den Wert aus TStream.Position und fangen an, ab dieser Position ihre Daten zu lesen.
Im Falle von TStringList.LoadFromStream würden also die "letzten" null Bytes geladen. Das wäre nicht so gut... Deshalb muß die Eigenschaft TStream.Position auf Null - also den Anfang des Streams - gesetzt werden. Dazu bietet sich die Methode TStream.Seek(Offset,Startpunkt) an. Bei TStream.Seek(0,soFromBeginning) wird also das erste Byte vom Anfang des Streams aus "angesteuert". Den selben Effekt hättest Du natürlich auch mit TStream.Position:=0.

ausblenden Delphi-Quelltext
1:
2:
OldDecimalSeparator := DecimalSeparator;
DecimalSeparator:='.';

In Delphi und im englischsprachigen Raum ist das Dezimal-Trennzeichen kein Komma, sondern ein Punkt. Wird jetzt ein String in eine Fließkommazahl umgewandelt, wird das im jeweiligen PC eingestellt Gebietsschema genutzt: Bei einer Fließkommazahl wird das also in der Regel ein Komma sein. Damit kann der String nicht richtig umgewandelt werden und es kommt bei StrToFloat() zu einer Exception.
Um das Ganze trotzdem hinzubekommen, kann über die globale Variable DecimalSeparator bzw. in neueren Delphi-Versionen FormatSettings.DecimalSeparator das Zeichen ausgewählt werden, das als Dezimal-Trennzeichen benutzt werden soll. Sehr zu empfehlen ist natürlich, den alten Wert zwischenzuspeichern und anschließend wieder herzustellen.

ausblenden Delphi-Quelltext
1:
2:
Version:=StrToFloatDef(Ini.Values['VersionCL'],0);
//...

StrToFloatDef erzeugt keine Exception, falls die Umwandlung eines Strings in eine Fließkommazahl nicht funktioniert, sondern nimmt im Fehlerfall einfach den übergebenen Wert. Ich kann allerdings nicht genau sagen, ab welcher Delphi-Version diese Funktion existiert.

TMemoryStream ist ein Stream, der nur im Speicher existiert, TFileStream arbeitet mit einer Datei auf der Festplatte.
Mit TIdHTTP.Get(URL,Stream) werden die empfangenen Daten im Stream gespeichert (in meinem Beispiel mit TMemoryStream nur im Hauptspeicher) und anschließend mit TMemoryStream.SaveToFile in eine Datei geschrieben. Das könnte man natürlich auch mit TFileStream realisieren. Ich wollte nur den Stream für die Versionsinformation für die eigentliche Datei wiederverwenden.
dYnAm1c Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 27.04.11 16:31 
Vielen Dank, bin ich schon wieder mal ein bisschen schlauer geworden, vorallem die Funktion
TMemoryStream gefällt mir, damit kann man ja praktisch auch verhindern das der User die Datei erhält wenn
man aus dieser nur Daten auslesen möchte.


mfg