Budujemy instalator cz. 2

załącznik
2006-01-23 16:36:00, wyświetleń: 3186 [ historia ]


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 załącznik

Autor: krajew4

Komentarze Artykuły mogą być komentowane wyłącznie przez zarejestrowanych użytkowników.
Maly46   2011-02-25 12:00:59
Może mógłby mi ktoś pomóc gdyż:Gdy wybieram aby zainstalował mi folder Jelcz 640 np. w katalogu:CProgram Files\MS2\DATA\CARS\To on mi instaluje takCProgram Files\MS2\DATA\CARSJelcz 640Pomocy
Rifi90   2007-01-28 00:51:52
Niezle, przyda sie
Redakcja zastrzega sobie prawo do skracania, usuwania komentarzy o treściach wulgarnych, obraźliwych oraz niezgodnych z polskim i miedzynarodowym prawem. Unit1.pl Team nie ponosi odpowiedzialności za treść komentarza.