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:
Wpisz INIFiles do uses
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
prawie to samo jest w kompendium programisty d7 Adama... ;]
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. ;)
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
Ja mam problem...[Error] Unit2.pas(53): Undeclared identifier: 'TINIFile'
Wiecie dlaczego?
ja nie mowie ze zerznales..mowie tylko ze kod adama to 1/3 tego
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
hej nie bulwersuj sie, na taka metode wpada sie po 5 sekundach myslenia o update'ach programu. Poza tym nawet ja nie pisze "sluwko"
Taki drobny problem - 1.9 będzie nowsza niż 2.1 :-) Lepiej skonwertować na floata.
TO samo (tzn podobny sposob, tyle ze prostszy) znajduje sie w ksiazce Adama (D7cwzaw) ciekawe.. :/
zapewniam Cię, lofix, że tej książki nie widziałem na oczy.
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.
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...
wyskakuje blad httpget, bo nie masz tego komponentu zainstalowanego [ot, caly problem]
A mi wyskakuje bląd cos SaveDialog1 undeclared? co to znaczy??
Teraz juz wiem..... moglem najpierw pomyslec, a pozniej dodac komentarz :)
uprałem sie z problemem xD jak ktoś nie wie to do uses trzeba dopisać IniFiles
a mi w tym miejscu kodu podkreśla błąd... o co chodzi??
INI : TINIFile;
Undeclared identifer: 'TINIfile'
używam delphi 7 personal
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 :]
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 :(((
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...
Kodzik ciekawy, mi się przyda niedługo :)
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ć =)
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...
Zapraszam na moją stronę www.programistakuty.pl. Tam prezentuje mój darmowy program (bardzo łatwo konfigurowalny) do aktualizacji programu. Prezentuje tam wykorzystanie go w delphi oraz dołączam przykładowy projekt. Strona artykułu http://programistakuty.pl/kuty-updater/
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ć [???]
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) then ...
ale jeśli program będzie np. w wersji 2.1 a ktoś nieszczęśliwie zapomni zaktualizować pliku na serwerze i tam będzie podane 1.9 to zacznie się nie upgrade, tylko DOWNGRADE (bo w tym wypadku 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
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 ??
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);
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.