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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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:
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 35 36 |
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:
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
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.
Autor: krajew4