Budujemy instalator cz. 2
Teraz zajmiemy się stworzeniem programu, który rozpakuje nasze pliki. Instalator ma być przyjazny dla użytkownika, więc musimy zaopatryć go w pasek postępu oraz w okienko informujące go ile potrzebuje wolnego miejsca na dysku. Żeby zdobyć nawyk profesjonalnego pisania programów, zajmiemy się również obsłużeniem wyjątków. Oczywiście poniższy sposób jest tylko szablonem, każdy wedle uznania może go zmodyfikować dodając np. własne logo czy coś w stylu "Uruchom aplikację (plik readme) po zamknięciu instalatora".
Zaczynamy od wstawienia komponentów na formę:
TEdit - name: katalog
TProgressBar - name: pbar
TButton - caption: Instaluj
TButton - caption: Przeglądaj
TLabel - name: wolnem (napis informujący o ilośći wymaganego wolnego miejsca na dysku)
Aha, najlepiej wygeneruj teraz przykładowe archiwum i skopiuj je do katalogu instalatora. Ułatwi to testowanie naszej aplikacji.
Najpierw okienko do wyboru katalogu:
Kod:
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
// uses FileCtrl
SelectDirectory('Wybierz katalog: ','My Computer',s);
if (s<>'') then
begin
katalog.Text:=s;
end;
end;
Teraz zaprogramujemy zdarzenie formy OnCreate, aby pokazywało na naszym labelu ile potrzeba wolnego miejsca na dysku:
Kod:
procedure TForm1.FormCreate(Sender: TObject);
var
f:TFileStream;
begin
if FileExists('files.dat')=false then
begin
MessageBox(0,'Plik z danymi nie istnieje!','Uwaga!',MB_OK+MB_ICONSTOP);
Application.Terminate;
end;
try
f:=TFileStream.Create('files.dat',fmOpenRead);
wolnem.Caption:='Wolne miejsce: '+IntToStr(round(f.Size/1024/1024))+' MB';
f.Free;
except
try f.Free; except end;
MessageBox(0,'Wystąpił nieoczekiwany błąd!','Uwaga!',MB_OK+MB_ICONSTOP);
end;
end;
No i wreszcie procedura odpowiedzialna za zainstalowanie naszego programu na dysku:
Kod:
procedure TForm1.Button2Click(Sender: TObject);
const
rozmiar_bufora=1024;
var
buf:array [1..rozmiar_bufora] of char; // bufor odczytu/zapisu
s:string;
fin,fout:TFileStream;
dl,ile,reszta,i,j:dword;
f_count:dword; // ile mamy plików
rozmiar:dword;
odp:integer;
dir:string;
z:char;
begin
if DirectoryExists(katalog.Text)=false then // jeżeli katalog nie istnieje
begin
odp:=Application.MessageBox(PCHAR('Podany katalog nie istnieje!'+#13+#10+'Czy chcesz go teraz utworzyć?'),'Uwaga!',MB_YESNO+MB_ICONQUESTION); // pytamy się czy stworzyć
if odp=ID_NO then // jeżeli nie to wychodzimy
exit;
if odp=ID_YES then
begin
if CreateDirectory(PCHAR(katalog.text),nil)=false then // spróbój stworzyć nowy katalog, jeżeli operacja się nie powiedzie to wychodzimy
begin
MessageBox(0,'Nie można utworzyć katalogu!','Uwaga!',MB_OK+MB_ICONSTOP);
exit;
end
else // jeżeli powiodło się to wywołaj jeszcze raz zdarzenie OnClick przycisku
button2.OnClick(button2); // Instaluj, tyle tylko, że teraz przejdzie do sekcji else, czyli, że
end; // katalog już istnieje
end
else // jeżeli katalog istnieje
begin
try
dir:=katalog.Text;
if dir[length(dir)]<>'' then dir:=dir+'';
fin:=TFileStream.Create('files.dat',fmOpenRead);
fin.Read(f_count,sizeof(f_count)); // odczytujemy ile jest plików
// przygotowujemy progressbar
pbar.Position:=0;
pbar.Max:=f_count;
for i:=1 to f_count do
begin
fin.Read(dl,sizeof(dl)); // długość nazwy pliku
s:='';
for j:=1 to dl do // odczytujemy nazwę pliku
begin
fin.Read(z,1);
s:=s+z;
end;
fin.Read(rozmiar,sizeof(rozmiar)); // rozmiar nowego pliku
ile:=rozmiar div rozmiar_bufora;
reszta:=rozmiar-(ile*rozmiar_bufora);
// sprawdzamy czy katalog w którym chcemy umieścić plik istnieje
// jeżeli nie to spróbójemy go utworzyć
// jeżeli to się nie powiedzie to wygenerujmy wyjątek
// i przejdziemy do sekcji except, która wyświeli stosowny komunikat
if (DirectoryExists(dir+ExtractFilePath(s))=false) then
begin
if ForceDirectories(PCHAR(dir+ExtractFilePath(s)))=false then
begin
dl:=strtoint('ble');
end;
end;
fout:=TFileStream.Create(dir+s,fmCreate or fmOpenWrite);
for j:=1 to ile do
begin
fin.Read(buf,sizeof(buf));
fout.Write(buf,sizeof(buf));
application.ProcessMessages;
end;
fin.Read(buf,reszta);
fout.Write(buf,reszta);
application.ProcessMessages;
pbar.Position:=pbar.Position+1;
fout.Free;
end;
fin.Free;
MessageBox(0,'Instalacja zakończona!','Uwaga!',MB_OK+MB_ICONINFORMATION);
except
try fin.Free; except end;
try fout.Free; except end;
MessageBox(0,'Wystąpił błąd podczas instalacji!','Uwaga!',MB_OK+MB_ICONSTOP);
end;
end;
end;
Mam nadzieję, że nie będziecie mieli problemu ze zrozumieniem tego kodu. Wszelkie wątpliwości wyjaśniłem w komentarzach.
I tak oto dobrnęliśmy do końca tego kursu. Teraz każdy z was będzie mógł przygotować w pełni profesjonalny instalator.
Pobierz załącznik
Autor: krajew4