Fajnie byłoby, aby program miał możliwość sprawdzenia, czy wyszła jego nowsza wersja. Zaprezentuję tutaj prosty sposób wg mojego pomysłu.

Potrzebne będą nam: konto na jakimś serwerze i komponent HTTPGet. Nie wiem, czy jest on na tej stronie, ale zamieszczam go do przykładowego programu, który znajdziecie w kodach źródłowych.

No więc zaczynamy.
Na początek stwórz plik version.ini. Potrzebny będzie, aby odczytać, czy wyszła nowa wersja programu. Plik będzie wyglądał tak:

[update]
version=1.3
url=http://www.web-page.pl/program.exe

Oczywiście url trzeba dostosować do swojej strony www.
Teraz przechodzimy do Delphi. Wrzuć na formę komponenty: Memo, Button, 2 HTTPGet i ProgressBar.
Wersję można wyciągnąć z zasobów, ale ja zadeklaruję tylko stałą:

 
const
  wersja = '1.2';
 


W zdarzeniu OnClick przycisku wpisz:

 
procedure TForm1.Button1Click(Sender: TObject);
begin
 HTTPGet1.URL := 'http://www.web-page.pl/version.ini';  //lokalizacja pliku z informacją
 HTTPGet1.FileName := ExtractFilePath(Application.ExeName) + 'version.ini'; 
 HTTPGet1.GetFile;  //pobranie pliku ini
 Memo1.Lines.Add('Pobieranie informacji...'); 
end;
 


Teraz w zdarzeniu onDoneFile komponentu HttpGet1 wpisz:

 
procedure TForm1.HTTPGet1DoneFile(Sender: TObject; FileName: String;
  FileSize: Integer);
var
 INI : TINIFile;
 updtVersion : string;
 cyfra1 : integer;
 cyfra2 : integer;
 updtCyfr1 : integer;
 updtCyfr2 : integer;
begin
 Memo1.Lines.Add('Sprawdzanie, czy jest nowa wersja');
 INI := TINIFile.Create(HTTPGet1.FileName);
 try
   updtVersion := INI.ReadString('update','version','');  //odcytanie wersji z pliku ini
 
   //nie śmiejcie sie z tego sposobu. To tylko przykład :)
   cyfra1 := StrToInt(wersja[1]);
   cyfra2 := StrToInt(wersja[3]);
   updtCyfr1 := StrToInt(updtVersion[1]);
   updtCyfr2 := StrToInt(updtVersion[3]);
   if (cyfra1 < updtCyfr1) or (cyfra2 < updtCyfr2) then  //sprawdzenie, czy jest nowa wersja
   begin
     Memo1.Lines.Add('Jest nowa wersja programu');
 
{wyświetlenie zapytania. Jeśli użytkownik wybierze Tak, rozpoczyna się pobieranie programu }
     if Application.MessageBox('Czy chcesz pobrać nową wersję programu?','Informacja',MB_YesNo) =
      ID_NO then
      exit
     else
      begin
       HTTPGet2.URL := INI.ReadString('update','url','');
       if SaveDialog1.Execute then  // tu użytkownik wybierze, gdzie zapisać program
         HTTPGet2.FileName := SaveDialog1.FileName;  
       HTTPGet2.GetFile;  //pobieranie pliku
       Memo1.Lines.Add('Pobieranie pliku');
      end;
   end
   else
      Memo1.Lines.Add('Nie znaleziono nowej wersji prormu');
 finally
   INI.Free;
   DeleteFile(HTTPGet1.FileName); //usunięcie pliku ini
 end;
 
end;
 


Następnie w OnError komponentu HttpGet1:

 
procedure TForm1.HTTPGet1Error(Sender: TObject);
begin
 Memo1.Lines.Add('Wystąpił błąd');
end;
 


Następnie w OnDoneFile komponentu HttpGet2:

 
procedure TForm1.HTTPGet2DoneFile(Sender: TObject; FileName: String;
  FileSize: Integer);
begin
 Memo1.Lines.Add('Pobieranie zakończone sukcesem');
end;
 


Teraz w OnError HttpGet2:

 
procedure TForm1.HTTPGet2Error(Sender: TObject);
begin
  Memo1.Lines.Add('Wystąpił błąd podczas pobierania pliku');
end;
 


No i na koniec w onProgress komponentu HttpGet2:

 
procedure TForm1.HTTPGet2Progress(Sender: TObject; TotalSize,
  Readed: Integer);
begin
  ProgressBar1.Max := TotalSize;
  ProgressBar1.Position := Readed;
end;
 


Teraz wystarczy tylko wrzucić plik version.ini na serwer.
To był oczywiście najprostszy sposób na uaktualnienie swojego programu, ale wystarczy troszkę wyobraźni i
rozbudowanie tego kodu nie będzie problemem.

pozdrawiam:
Piotrek Chmolowski

Kod przykładowego programu możecie pobrać tutaj:

http://4programmers.net/download.html?id=1036

Kategoria: Delphi » Gotowce

29 komentarzy

Brak avatara
Napisany 2011-08-07 11:50 przez BoZzDoG

Wklejam kod funkcji, która sprawdza czy jest nowa wersja programu bazując na dwóch plikach:

function TMainForm.IsNewVesrion(const VersionFileName, UpdateFileName: ShortString): Boolean;
var
  {ZMIENNE PLIKOWE}
  iniVersion, iniUpdate: TINIFile;
  {ZMIENNA LICZNIKOWA}
  I: Byte;
begin
  {DOMYŚLNY REZULTAT FUNKCJI}
  Result := False;

  try
    {TWORZENIE ZMIENNYCH PLIKOWYCH}
    iniVersion := TINIFile.Create(VersionFileName);
    iniUpdate := TINIFile.Create(UpdateFileName);

    {SPRAWDZANIE POSZCZEGÓLNYCH LICZB WERSJI}
    for I := 0 to 3 do
      if iniUpdate.ReadInteger('CURRENT_VERSION', IntToStr(I), 0) > iniVersion.ReadInteger('CURRENT_VERSION', IntToStr(I), 0) then
        begin
          {JEŚLI JEST WYŻSZA LICZBA WERSJI ZWRÓĆ TRUE}
          Result := True;
          Break;
        end;
  finally
   {USUŃ ZMIENNE PLIKOWE Z PAMIĘCI}
    FreeAndNil(iniVersion);
    FreeAndNil(iniUpdate);
  end;
end;

Budowa plików jest prosta. Oto plik Version.ini - są w nim informacje na temat aktualnie posiadanej wersji programu:

[CURRENT_VERSION]
0=1
1=0
2=0
3=154

A to zawartość pliku Update.ini - jest to plik pobrany z sieci przechowujący informacje na temat najnowszej wersji programu:

[CURRENT_VERSION]
0=1
1=0
2=0
3=157

Jak widać jest w nim młodsza wersja programu, stąd funkcja zwróci prawdę. Algorytm nie myli się i nalezy go używać tuż po pobraniu pliku wersji z Internetu. Pozdrawiam.

Brak avatara
Napisany 2011-08-07 10:59 przez BoZzDoG

BTW: A poza tym algorytm nie jest w pełni poprawny, by jeżeli wersja aplikacji wzrośnie do 10, program odczyta go jako 1...

Metoda z liczbami jest uniwersalna, na łańcuchach niestety nie...

Brak avatara
Napisany 2011-08-07 10:57 przez BoZzDoG

Witajcie. Dlaczego wersję programu odczytujecie jako łańcuch? Przecież klasa TINIFile posiada możliwość odczytywania zawartości kluczy jako liczb metodą INI.ReadInteger... Zamiast kombinować z konwertowaniem tekstu na liczby wystarczy podzielić numer wersji na bloki i je porównywać (zawartość pliku version.ini):

[CURRENT_VERSION]
Major=1
Minor=0
Release=0
Build=2043

Teraz pobrać do odpowiednich zmiennych te liczby i porównać. Można by było zapisać je do tablicy i jedną pętlą sprawdzić czy wersja aplikacji w pliku version.ini jest nowsza niż tej na dysku. No ale trzeba by było trochę pogłówkować =)

Brak avatara
Napisany 2010-07-11 16:14 przez pawel8115

Czy mógł by ktoś zamieścić kod żródłowy tego programu , ponieważ niewiem dlaczego ale wywala mi błąd podczas kliknięcia na button .
bład jest w tej linijce :

   updtCyfr1 := StrToInt(updtVersion[1]);
 
kod programu :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IniFiles, XPMan, ComCtrls, StdCtrls, HTTPGet;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    ProgressBar1: TProgressBar;
    XPManifest1: TXPManifest;
    SaveDialog1: TSaveDialog;
    HTTPGet1: THTTPGet;
    HTTPGet2: THTTPGet;
    procedure Button1Click(Sender: TObject);
    procedure HTTPGet1DoneFile(Sender: TObject; FileName: String;
      FileSize: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  wersja = '1.2';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 HTTPGet1.URL := 'http://www.pm2a.yoyo.pl/updater/version.ini';  //lokalizacja pliku z informacją
 HTTPGet1.FileName := ExtractFilePath(Application.ExeName) + 'version.ini';
 HTTPGet1.GetFile;  //pobranie pliku ini
 Memo1.Lines.Add('Pobieranie informacji...');
end;

procedure TForm1.HTTPGet1DoneFile(Sender: TObject; FileName: String;
  FileSize: Integer);

  var
 INI : TINIFile;
 updtVersion : string;
 cyfra1 : integer;
 cyfra2 : integer;
 updtCyfr1 : integer;
 updtCyfr2 : integer;
begin
 Memo1.Lines.Add('Sprawdzanie, czy jest nowa wersja');
 INI := TINIFile.Create(HTTPGet1.FileName);
 try
   updtVersion := INI.ReadString('update','version','');  //odcytanie wersji z pliku ini

   //nie śmiejcie sie z tego sposobu. To tylko przykład :)
   cyfra1 := StrToInt(wersja[1]);
   cyfra2 := StrToInt(wersja[3]);
   updtCyfr1 := StrToInt(updtVersion[1]);
   updtCyfr2 := StrToInt(updtVersion[3]);
   if (cyfra1 < updtCyfr1) or (cyfra2 < updtCyfr2) then  //sprawdzenie, czy jest nowa wersja
   begin
     Memo1.Lines.Add('Jest nowa wersja programu');

{wyświetlenie zapytania. Jeśli użytkownik wybierze Tak, rozpoczyna się pobieranie programu }
     if Application.MessageBox('Czy chcesz pobrać nową wersję programu?','Informacja',MB_YesNo) =
      ID_NO then
      exit
     else
      begin
       HTTPGet2.URL := INI.ReadString('update','url','');
       if SaveDialog1.Execute then  // tu użytkownik wybierze, gdzie zapisać program
         HTTPGet2.FileName := SaveDialog1.FileName;
       HTTPGet2.GetFile;  //pobieranie pliku
       Memo1.Lines.Add('Pobieranie pliku');
      end;
   end
   else
      Memo1.Lines.Add('Nie znaleziono nowej wersji prormu');
 finally
   INI.Free;
   DeleteFile(HTTPGet1.FileName); //usunięcie pliku ini
 end;
end;

end.

Co w nim jest nie tak ??

Avatar: siekierzyński
Napisany 2009-11-14 23:26 przez siekierzyński

Kodzik ciekawy, mi się przyda niedługo :)

Avatar: maxi
Napisany 2008-06-08 16:20 przez maxi

na yoyo żeby ściągać plik przez HTTP nigdzie się nie musisz logować, nie wiem skąd to wziąłeś

nav, pisałem o tym trochę niżej...

Brak avatara
Napisany 2008-02-07 16:59 przez rysio93

a znacie może jakaś dobra stronkę gdzie by założyć konto ?? bo na yoyo trzeba sie zalogować żeby ściągnąć plik na cba.pl i republice tez :(((

Brak avatara
Napisany 2009-12-23 22:09 przez sitcome

Zawsze można zrobić tak że na serwerze jest plik np. nazwa_numer.wersji i przy odpalaniu program próbuje pobrać ten plik jeśli go nie ma na serwerze,  to nie ma aktualizacji wydaje mi się za bardzo prymitywna wersja jest chyba najlepsza :]

Brak avatara
Napisany 2007-09-13 14:05 przez siwy16l

a mi w tym miejscu kodu podkreśla błąd... o co chodzi??
INI : TINIFile;

Undeclared identifer: 'TINIfile'

używam delphi 7 personal

Brak avatara
Napisany 2007-09-13 21:08 przez siwy16l

uprałem sie z problemem xD jak ktoś nie wie to do uses trzeba dopisać IniFiles

Avatar: bordeux
Napisany 2007-05-16 17:33 przez bordeux

Teraz juz wiem..... moglem najpierw pomyslec, a pozniej dodac komentarz :)

Avatar: maxi
Napisany 2007-04-11 19:41 przez maxi

bordeux, nie dodałeś komponentu SaveDialog na formatkę.

Mam jedną uwagę dot. linijki 21 z procedury TForm1.HTTPGet1DoneFile. Tam jest:

if (cyfra1 < updtCyfr1) or (cyfra2 <> updtCyfr2)! To jest sytuacja wyjątkowa spowodowana przez osobę opiekującą się serwerem, ale pamięć ludzka jest zawodna więc proponuję takie coś:

if (cyfra1 < updtCyfr1) or ((cyfra1 = updtCyfr1) and (cyfra2 < updtCyfr2)) then ...

chyba będzie działać, ale nie jestem pewny bo dopiero zaczynam przygodę z Delphi

Avatar: bordeux
Napisany 2007-03-18 12:10 przez bordeux

A mi wyskakuje bląd cos SaveDialog1 undeclared? co to znaczy??

Brak avatara
Napisany 2007-02-23 16:29 przez sochalewski

wyskakuje blad httpget, bo nie masz tego komponentu zainstalowanego [ot, caly problem]

Avatar: Armi
Napisany 2006-03-31 16:29 przez Armi

Mam mały problem w use występuje mi błąd   [Fatal Error] Unit1.pas(7): File not found: 'HTTPGet.dcu' i zaznacza mi się HTTPGet prosze poradzcie mi co mam z tym zrobić [???]

Avatar: Thomashek
Napisany 2005-01-02 19:11 przez Thomashek

Wpisz INIFiles do uses

Brak avatara
Napisany 2004-12-05 20:57 przez JarekM

Ja mam problem...[Error] Unit2.pas(53): Undeclared identifier: 'TINIFile'

Wiecie dlaczego?

Avatar: migajek
Napisany 2004-11-28 12:32 przez migajek

Swoją drogą, co wy tak macie z tym HTTPGet ? ;) Ja tam wolę stare dobre UrlDownloadToFile, bo mozna go zastosować wszędzie, również programując w API. I dzięki temu mój programik Downloader nie musi mieć formy w dfm ani classes w uses :P

Avatar: kubARek
Napisany 2004-04-04 13:17 przez kubARek

dzieki. moze sie przydac :)
a wiecie ze ja znalazlem gdzies w sieci opis uzycia OpenDialog. Slowko w slowko to samo ;) Musieli zerznac z ksiazki Adama B. ;)

Avatar: czarownik
Napisany 2004-02-02 12:36 przez czarownik

prawie to samo jest w kompendium programisty d7 Adama... ;]

Avatar: piwko28
Napisany 2004-01-06 20:07 przez piwko28

Zgadzam sie z Wolverinem, na taki sam pomysl wpadlem podczas pisania swojego programu. Bo najlatwiej go zrealizowac :P

Dobre do czasu, do kiedy nie usuna Ci konta (na bezplatnym serwerze) :D

Avatar: Wolverine
Napisany 2003-12-30 14:04 przez Wolverine

hej nie bulwersuj sie, na taka metode wpada sie po 5 sekundach myslenia o update'ach programu. Poza tym nawet ja nie pisze "sluwko"

Brak avatara
Napisany 2003-10-05 14:30 przez Adam's

zerżnołeś albo ktoś zerżną z ciebie słuwko w słuwko znalazłem to na koder.prv.pl
// o mamo, ale byki... - ŁF

Avatar: lofix
Napisany 2003-07-15 12:50 przez lofix

ja nie mowie ze zerznales..mowie tylko ze kod adama to 1/3 tego

Brak avatara
Napisany 2003-07-10 12:19 przez Krzemin

Nawet niezłe, ale powien Ci co ja zrobiłem : na serwerku walnąłem plik textowy w takim formacie :

NAZWAPLIKU;URL_DO_NIEGO

W ten sposób można zamieścić nie tylko jedną wersję, ale np. uaktualnienia do bibliotek (jeśli ich używamy), starsze wersje programu itp...

Brak avatara
Napisany 2003-07-10 16:15 przez chmolu

Przecież mój sposób bardzo łatwo rozbudować.
Wystarczy jakiś pomysł. Można np. dać drugi link do pliku z informacją co nowego w programie.

Brak avatara
Napisany 2003-07-12 11:14 przez chmolu

zapewniam Cię, lofix, że tej książki nie widziałem na oczy.

Avatar: lofix
Napisany 2003-07-12 09:43 przez lofix

TO samo (tzn podobny sposob, tyle ze prostszy) znajduje sie w ksiazce Adama (D7cwzaw) ciekawe.. :/

Avatar: nav
Napisany 2007-11-15 21:48 przez nav

Taki drobny problem - 1.9 będzie nowsza niż 2.1 :-) Lepiej skonwertować na floata.

4programmers.net