R18-03, ## Documents ##, C++Builder 5


Rozdział 18.
Instalowanie i aktualizowanie oprogramowania

Simon Rutley-Frayne

J. Alan Brogan

Yoto Yotov

Instalacja i dezinstalacja oprogramowania

Pliki CAB i INF

Wersje, uaktualnienia i poprawki

System kontroli wersji TeamSource

Program InstallShield Express

Obecnie zajmiemy się narzędziami zapewniającymi możliwie bezkonfliktowe instalowanie i konserwację oprogramowania, mającymi zastosowanie zarówno dla aplikacji komercyjnych, jak i programów klasy shareware. Na techniczną stronę rozdziału złoży się omówienie programów Install Maker i Patch Maker firmy ClickTeam, formatów CAB i INF oraz dostarczanego w pakiecie C++Builder programu InstallShield Express. Zajmiemy się także kwestią konserwacji oprogramowania, powiemy kilka słów na temat tworzenia i rozpowszechniania uaktualnień i poprawek oraz przedstawimy wprowadzenie do systemu kontroli wersji TeamSource.

Instalacja i dezinstalacja oprogramowania

Skompilowanie i uruchomienie aplikacji nie jest bynajmniej ostatnim etapem jej tworzenia. Niezbędne jest udostępnienie użytkownikowi narzędzia pozwalającego zainstalować wszystkie elementy programu w systemie docelowym w sposób niekłopotliwy i zapewniający poprawną pracę aplikacji. Narzędziem takim jest program instalacyjny (instalator), umieszczający w komputerze użytkownika odpowiednie pliki i zmieniający ustawienia systemu. Program taki powinien oczywiście być łatwy w obsłudze, działać możliwie automatycznie i wymagać od użytkownika minimalnych kwalifikacji.

Na rynku oprogramowania dostępnych jest kilka narzędzi do tworzenia programów instalacyjnych, począwszy od prostych programików dostępnych za darmo, a skończywszy na zaawansowanych i kosztownych „kombajnach”. Więcej informacji na ich temat, łącznie z adresami witryn WWW producentów, zamieszczono na końcu tego podrozdziału.

Narzędzia do tworzenia programów instalacyjnych

Pod względem zasad obsługi narzędzia przeznaczone do tworzenia programów instalacyjnych są zbliżone do C++Buildera, chociaż korzystanie z ich funkcji jest znacznie prostsze. Budowa programu instalacyjnego sprowadza się na ogół do utworzenia skryptu sterującego instalacją, skompilowania go, dołączenia i skompresowania plików wchodzących w skład instalowanej aplikacji oraz zdefiniowania elementów interfejsu użytkownika. Wynikiem takiej procedury jest utworzenie pliku (lub kilku plików) przeznaczonego do bezpośredniej dystrybucji.

Jak to działa?

Tworzenie programu instalacyjnego sprowadza się w większości przypadków do wprowadzenia odpowiednich informacji (nazwy instalowanych plików, położenie katalogu docelowego, informacje wyświetlane podczas instalacji, treść licencji itd.) w oknach kreatora. Dane te zapisywane są w postaci skryptu, sterującego następnie kompilacją wszystkich elementów do postaci właściwego pliku instalacyjnego.

Program instalacyjny może mieć postać pojedynczego pliku lub kilku plików. W obu przypadkach efekt instalacji jest ten sam, jednak każde z rozwiązań ma swoje wady i zalety, o których powiemy teraz kilka słów.

Jeden czy kilka --> plików[Author:ts] ?

Podstawową zaletą umieszczenia programu instalacyjnego w pojedynczym pliku jest wygoda - plik taki łatwo jest umieścić np. na płycie CD-ROM. Z drugiej strony użycie tej metody utrudnia dystrybucję za pomocą dyskietek, gdyż rozmiary plików instalacyjnych często przekraczają 1,44 megabajta. Rozbicie programu instalacyjnego na kilka fragmentów niesie także ze sobą większe ryzyko zgubienia któregoś z nich, co zwykle uniemożliwia poprawne zainstalowanie całości programu. Z drugiej strony warto zauważyć, że uszkodzenie pojedynczego pliku może skutecznie uniemożliwić jakąkolwiek instalację (nawet częściową), podczas gdy korzystając z kilku plików, można próbować wyeliminować uszkodzony plik z procesu instalacji. Kilka mniejszych plików łatwiej też jest pobrać np. z Internetu.

Program Install Maker

Opracowany przez firmę ClickTeam program Install Maker jest dostępny w dwóch wersjach - komercyjnej (odpłatnej) oraz bezpłatnej (freeware), uzupełniającej tworzony plik instalacyjny o końcowe okno z reklamą producenta. Użytkownicy zainteresowani nabyciem wersji licencjonowanej znajdą niezbędne informacje pod adresem http://www.clickteam.com.

Tworzenie instalatora za pomocą narzędzia Install Maker

Program Install --> Maker [Author:ts] (w wersji freeware) można pobrać z witryny WWW firmy ClickTeam. Jest on idealnym narzędziem do tworzenia prostych programów instalacyjnych, nie wymagających manipulowania bardziej zaawansowanymi elementami systemu, jak sterowniki obsługujące dostęp do baz danych lub rejestr systemowy (w razie konieczności skorzystania z bardziej złożonych funkcji najlepiej użyć programu InstallShield). Install Maker wyróżnia się także dobrym współczynnikiem kompresji, dzięki czemu tworzone przezeń pliki są stosunkowo niewielkie.

Przyjrzyjmy się zatem, w jaki sposób można utworzyć program instalacyjny za pomocą narzędzia Install Maker. Kolejne etapy konstrukcji opiszemy poniżej.

  1. Okno powitalne

Pierwszym oknem wyświetlanym po zainstalowaniu i uruchomieniu programu Install Maker jest okno powitalne. Widoczne w dolnej części pole wyboru pozwala zrezygnować z usług kreatora i przejść bezpośrednio do głównego okna programu. Nowicjuszom zaleca się raczej pozostanie w trybie kreatora, który umożliwia łatwiejsze zapoznanie się z programem.

  1. Ustalenie katalogu --> źródłowego [Author:ts]

W kolejnym kroku należy określić położenie plików, które mają wejść w skład pakietu instalacyjnego. Najlepszą metodą jest umieszczenie wszystkich plików w jednym katalogu (ewentualnie w jego podkatalogach), np. MojaFirma\MojProgram. Install Maker odczytuje zawartość takiego katalogu podczas kompilacji (zaznaczenie pola wyboru Include sub-directories nakazuje przeszukanie także podkatalogów; opcja ta jest domyślnie włączona) i kompresuje ją do postaci jednego pliku wykonywalnego. Uruchomienie tak utworzonego programu rozpakuje wszystkie pliki do zadanego katalogu w komputerze docelowym.

  1. Ustalenie tytułu aplikacji i języka programu instalacyjnego

Kolejne okno kreatora pozwala na wybranie języka programu instalacyjnego (ClickTeam jest firmą francuską, dlatego też oprócz języka angielskiego mamy do wyboru także francuski). Drugim parametrem ustalanym w tym kroku jest „długa” nazwa instalowanego programu, która będzie wyświetlana podczas instalacji. Warto przy tej okazji zwrócić uwagę na przycisk Preview (podgląd), którego kliknięcie pozwala wyświetlić tworzone właśnie okno w postaci, w jakiej będzie je oglądał użytkownik.

  1. Definiowanie ustawień powłoki

Okno zatytułowane Shell (powłoka) pozwala wybrać plik, który będzie reprezentowany w postaci ikony i polecenia w menu Start|Programy, a także ustalić nazwę tego polecenia. Zaznaczenie pola wyboru Add desktop shortcut nakazuje umieszczenie ikony skrótu na pulpicie, co jednak nie jest zalecane, gdyż przyczynia się do jego zatłoczenia.

  1. Informacje dodatkowe

Kolejne okno umożliwia wpisanie tekstu informacyjnego, wyświetlanego w trakcie instalowania programu (np. umowa licencyjna, informacje o nowych elementach itp.). Tekstu nie da się co prawda odczytać z pliku, jednak w razie potrzeby można wkleić do okna zawartość schowka skopiowaną np. z okna Notatnika. Wklejony tekst należy także odpowiednio sformatować. Faktyczny wygląd okna można w każdej chwili obejrzeć, klikając przycisk Preview.

  1. Definiowanie ustawień ekranu i okna instalatora

W następnym etapie można zdecydować, czy program instalacyjny ma pracować jako zwykłe okno czy w trybie pełnoekranowym. Znajdujące się w dolnej części pole edycyjne pozwala wpisać nazwę, która w trybie pełnoekranowym będzie wyświetlana w lewym górnym rogu ekranu.

  1. Wybór obrazków

Kolejne okno kreatora pozwala wybrać obrazek wyświetlany w lewej części okna programu instalacyjnego oraz „tapetę” zastępującą standardowe gradientowe tło. Warto tu zachować wstrzemięźliwość, gdyż dołączenie każdego pliku do programu instalacyjnego powoduje wzrost jego rozmiarów. Nie jest to problemem, jeśli program ma zostać umieszczony na płycie CD-ROM, ale w przypadku dystrybucji internetowej lub z wykorzystaniem dyskietek należy zadbać, by rozmiary utworzonego pliku (lub plików) były jak najmniejsze - o ile oczywiście nie chcemy narażać się użytkownikom.

Mapa bitowa wyświetlana w lewej części poszczególnych okien instalatora musi być zapisana w postaci pliku BMP, mieć określone rozmiary (128 na 280 pikseli) i co najwyżej 256 kolorów. Wygląd okna po wybraniu odpowiedniego pliku można podejrzeć, klikając przycisk Preview. Druga mapa bitowa definiuje postać tła w przypadku pracy w trybie pełnoekranowym. Odpowiedni obrazek również musi pochodzić z pliku BMP i zawierać nie więcej niż 256 kolorów, jednak jego rozmiary mogą być dowolne, jest on bowiem układany sąsiadująco na całej powierzchni ekranu. Również i w tym przypadku pomocny okazuje się przycisk Preview.

  1. Ustalenie katalogu docelowego

Okno Installation directory umożliwia ustalenie domyślnej nazwy katalogu, w którym zostanie zainstalowana aplikacja, np. C:\Program Files\FirmaKogucik\Kadry1.0. Kliknięcie przycisku Dalej pozwala użytkownikowi zaakceptować wartość domyślną, zwalniając go z konieczności ustalania docelowego katalogu aplikacji (oczywiście w razie potrzeby zawsze można to zrobić). Warto pamiętać, że chociaż domyślna lokalizacja katalogu docelowego może być dowolna, użycie dysku innego niż C: jest nieco ryzykowne (dysk ten jest obecny w praktycznie każdym systemie).

W razie potrzeby można też nakazać instalatorowi odczytanie nazwy katalogu docelowego z rejestru lub pliku INI.

  1. Zakończenie instalacji

Kolejne okno kreatora umożliwia określenie nazwy pliku, zawierającego istotne informacje (zwykle Czytaj lub Readme) lub np. umowę licencyjną. Zawartość pliku jest wyświetlana w oknie Notatnika po kliknięciu przycisku View…. Drugie z dostępnych na ekranie pól edycyjnych umożliwia podanie nazwy programu uruchamianego po zakończeniu instalacji (zwykle jest to plik wykonywalny instalowanej aplikacji).

  1. Opcja dezinstalacji

Okno wyświetlane w kolejnym kroku zawiera tylko jedną opcję, której wybranie nakazuje kreatorowi utworzenie programu dezinstalującego (ang. uninstall). Pole wyboru opcji jest domyślnie zaznaczone; stanu tego najlepiej nie zmieniać, gdyż pozbawiłoby to użytkownika możliwości łatwego usunięcia aplikacji z komputera.

Zaznaczenie pola wyboru Uninstall program powoduje utworzenie przez program instalacyjny małego pliku wykonywalnego, którego uruchomienie automatycznie usuwa całą zainstalowaną aplikację. Program dezinstalujący można uruchomić bezpośrednio (tj. przez kliknięcie jego ikony) lub pośrednio, za pomocą apletu Dodaj/Usuń programy w Panelu sterowania.

  1. Okno końcowe

Ostatnie z okien wyświetlanych przez kreatora również zawiera tylko jedną opcję, pozwalającą wyłączyć kompilację pliku wynikowego instalatora. Jeśli informacje wprowadzone w poprzednich krokach są poprawne, kliknięcie przycisku Dalej spowoduje utworzenie pliku programu instalacyjnego. W razie wątpliwości zawsze można cofnąć się do poprzednich kroków, klikając przycisk Wstecz.

  1. Kompilacja pliku wynikowego instalatora

Kliknięcie przycisku Dalej bez zaznaczania pola wyboru Do not build the Install program powoduje wyświetlenie okna zapisania pliku, umożliwiającego ustalenie nazwy i lokalizacji tworzonego programu instalacyjnego. Nie ma w tej kwestii żadnych ograniczeń, jednak należy pamiętać, by nie umieszczać tworzonego pliku w katalogu zawierającym pliki źródłowe aplikacji - podczas ponownych kompilacji powodowałoby to dołączanie pliku wykonywalnego instalatora do nowo tworzonych wersji.

Po utworzeniu pliku instalatora warto zapisać całość projektu (łącznie ze skryptem, zapisywanym w pliku o rozszerzeniu .iit), co pozwoli na łatwe wprowadzanie poprawek i uaktualnień w przyszłości.

Do sprawdzenia działania nowo utworzonego programu najlepiej posłużyć się tą samą metodą, którą zastosuje jego odbiorca, czyli uruchomić go z poziomu Eksploratora Windows. Po zakończeniu testowania instalatora w systemie źródłowym należy zawsze sprawdzić jego działanie na innym komputerze i upewnić się, że zainstalowana w ten sposób aplikacja będzie zachowywała się poprawnie. W razie niepowodzenia wystarczy zmienić ustawienia skryptu i wykonać kolejny przebieg kompilacji i testowania, pamiętając o uprzednim odinstalowaniu poprzedniej wersji.

  1. Tworzenie dodatkowych skrótów w menu Start

Program instalacyjny zdefiniowany za pomocą kreatora można wzbogacić o funkcję tworzenia dodatkowych skrótów w menu Start (oddzielną pozycję menu można np. utworzyć dla głównego pliku pomocy aplikacji lub dokumentu Czytaj). Aby to uczynić, należy kliknąć zakładkę Files w głównym oknie programu Install Maker i wybrać z listy plik, który ma zostać udostępniony w menu. W prawej części okna, w polu File Options, znajduje się karta Start menu, zawierająca pola edycyjne Folder i Name. Zawartość pierwszego z nich określa nazwę podmenu zawierającego dany skrót, zaś drugiego - nazwę skrótu (polecenia) w podmenu.

Uwaga
Dodatkowe skróty najlepiej jest umieszczać w tym samym podmenu, co „główny” skrót do programu - odpowiednią nazwę podmenu należy wpisać w polu Folder.

Dezinstalacja programu

Ponieważ nasza aplikacja może z różnych przyczyn nie znaleźć aprobaty użytkownika, wypadałoby umożliwić mu łatwe, bezkonfliktowe i skuteczne usunięcie zainstalowanych plików (i innych elementów programu) z komputera. Większość narzędzi tworzących programy instalacyjne, w tym Install Maker, automatycznie dołącza odpowiednie składniki do tworzonego programu, co zwalnia nas z zajmowania się szczegółami procesu dezinstalacji.

Powszechnie wiadomo, że wiele aplikacji nie potrafi odinstalować się całkowicie, dlatego też programy „sprzątające”, jak np. CleanSweep, wciąż cieszą się popularnością. Nie zmienia to faktu, iż tworząc program dezinstalatora należy w miarę możliwości zadbać, by aplikacja usuwana z systemu użytkownika nie pozostawiła po sobie „bezpańskich” plików czy wpisów w rejestrze. Oczywistą metodą sprawdzenia skuteczności dezinstalacji jest sporządzenie spisu wszystkich składników instalowanych w systemie docelowym, zainstalowanie aplikacji, a następnie jej odinstalowanie i sprawdzenie, czy wszystkie elementy zostały prawidłowo usunięte. Jakiekolwiek pozostałości powinny wynikać co najwyżej z dodania przez użytkownika własnych plików i katalogów (zakładając, że procedura dezinstalacji została wykonana i działa poprawnie). Automatyczne usunięcie wszystkich plików jest praktycznie niemożliwe, bowiem program odinstalowujący „wie” tylko o komponentach (plikach, wpisach do rejestru itp.) dodanych do systemu w czasie instalowania, nie śledzi natomiast elementów utworzonych przez użytkownika w trakcie korzystania z aplikacji, a zatem nie może ich usunąć. Efekt ten jest dość pospolity i przejawia się na ogół w wyświetleniu przez dezinstalator komunikatu o niemożności usunięcia niektórych plików (komunikat Some elements could not be removed). Przyczyną takiego stanu jest obecność w katalogu macierzystym aplikacji dodatkowych plików, utworzonych poza kontrolą programu instalacyjnego (np. w wyniku działania samej aplikacji). Może się także okazać, że któryś z zainstalowanych elementów powinien pozostać w systemie nawet po usunięciu aplikacji, do której należy. Ma to miejsce głównie dla bibliotek dynamicznych, które mogą okazać się niezbędne do poprawnej pracy systemu. W takiej sytuacji dezinstalator prosi zwykle użytkownika o potwierdzenie zamiaru usunięcia pliku.

Install Maker nie jest jedynym dostępnym narzędziem do tworzenia programów instalacyjnych. Adresy witryn internetowych kilku konkurencyjnych produktów podano poniżej.

Setup Factory - http://www.indigorose.com/

Inno Setup - http://www.jordanr.dhs.org/

Soysal Setup - http://www.soysal.com/ssetup

Wise Setup - http://www.wisesolutions.com/imakfeat.htm

Pliki CAB i INF

Pliki typu CAB oraz INF (plik informacji instalacyjnych, ang. information file) są popularnymi i efektywnymi narzędziami dystrybucji oprogramowania oraz aplikacji internetowych. Ich ścisła integracja z mechanizmami przeglądarki Microsoft Internet Explorer umożliwia automatyzację procesów instalacji i kontroli wersji. Kilka kolejnych stron poświęcimy zatem tworzeniu plików CAB i INF.

Pliki CAB

Nikogo nie trzeba przekonywać, że im mniejszy rozmiar pliku, tym łatwiej jest go przechowywać i przesyłać. Remedium na przerośnięte pliki jest kompresja danych, polegająca z grubsza na wykrywaniu pewnych regularności w sekwencjach bitów tworzących zawartość pliku i zastępowaniu takich wzorców odpowiednimi kodami, zajmującymi znacznie mniej miejsca. Kompresję wykorzystuje również opracowany przez firmę Microsoft format CAB (tzw. plik szafki, ang. cabinet file), oparty na popularnym algorytmie Lempela-Ziva. W formacie CAB rozpowszechniany jest m.in. pakiet Microsoft Office, a także sam system Windows (zobacz rysunek 18.1).

Rysunek 18.1. Pliki CAB zawierające system Microsoft Windows

W tym miejscu należałoby zadać sobie pytanie, czy i dlaczego warto używać akurat formatu CAB. Oprócz skrócenia czasu przesyłania plików (co jest oczywistym celem stosowania kompresji), użycie plików CAB jest obecnie najłatwiejszą metodą dystrybucji w Internecie komponentów ActiveX i klas Javy. Programiści mają także do dyspozycji opracowany przez Microsoft pakiet Cabinet SDK, czyli komplet narzędzi programowych obsługujących format CAB.

Uwaga
Jeden z elementów pakietu Cabinet SDK, program CABARC, wchodzi również w skład systemu C++Builder. O pozostałe narzędzia należy niestety postarać się samemu, pobierając je np. ze strony położonej pod adresem http://msdn.microsoft.com/workshop/management/cab/cabdl.asp.

Tworzenie i rozpakowywanie plików CAB

W skład pakietu Cabinet SDK wchodzą trzy programy narzędziowe, umieszczane w podkatalogu CabSDK\Bin:

Jak widać, wachlarz możliwości jest dość szeroki, jednak tutaj ograniczymy się do programu CABARC, zapewniającego wystarczający na nasze potrzeby zestaw funkcji (poza tym tylko on dostarczany jest standardowo w pakiecie C++Builder).

Wykaz dostępnych funkcji najprościej uzyskać poprzez wydanie w oknie DOS-u polecenia CABARC. Wywołanie programu ma ogólną postać

CABARC [opcje] polecenie plik-CAB [@lista] [pliki] [katalog]

zaś jego parametry zestawiono w tabeli 18.1.

Tabela 18.1. Parametry wywołania programu --> CABARC[Author:ts]

Polecenie

Znaczenie

Przykład

l

Wyświetlenie zawartości pliku CAB

cabarc l test.cab

n

Utworzenie nowego pliku CAB

cabarc n test.cab *.c app.mak *.h

x

Rozpakowanie (odtworzenie plików) pliku CAB

cabarc x test.cab prog*.c

Opcja

Znaczenie

Wartości

-c

Żądanie potwierdzenia dla poszczególnych plików

-o

Zastępowanie już istniejących plików bez potwierdzenia (podczas odtwarzania)

-m

Wybór algorytmu kompresji

LZX:<15..21>, MSZIP lub NONE
domyślnie MSZIP

-p

Zapisywanie pełnych ścieżek plików (dozwolone tylko ścieżki względne)

-P

Usunięcie zadanego przedrostka z nazw plików

Przedrostek (np. nazwa katalogu)

-r

Przeszukanie katalogu wraz z podkatalogami (podczas tworzenia archiwum, zob. też -p)

-s

Zarezerwowanie obszaru w pliku CAB na podpis cyfrowy

Rozmiar obszaru, np. 6144 = 6 kB

-i

Ustalenie identyfikatora zestawu plików (domyślnie zero)

Wartość identyfikatora

Umieszczenie na liście nazw plików znaku + (plus) podczas tworzenia archiwum (np. cabarc n test.cab *.c test.h + *.bmp) wymusza spakowanie następujących po nim plików do nowego katalogu. Nazwa katalogu docelowego podawana podczas rozpakowywania musi kończyć się lewym ukośnikiem (np. cabarc x test.cab prog*.cpp *.h d:\test\). Wreszcie opcja -P (usunięcie przedrostka) pozwala na usunięcie z nazw plików zadanego fragmentu ścieżki (np. polecenie cabarc -r -p -P projekty\ test.cab projekty\graf\*.* usunie ze ścieżek fragment projekty\). Opcję tę można wykorzystać kilkakrotnie do usunięcia kilku różnych fragmentów ścieżek.

Wskazówka
Źródłem informacji na temat narzędzi dostępnych w pakiecie Cabinet SDK oraz przykładów ich użycia jest dokumentacja zawarta w podkatalogu Docs.

Tworzenie archiwów CAB (kompresja) i odtwarzanie ich zawartości (dekompresja) sprowadza się w zasadzie do użycia odpowiednich parametrów wywołania programu CABARC. Na przykład do spakowania wszystkich plików DLL zawartych w bieżącym katalogu służy polecenie:

cabarc n archiwum.cab *.dll

zaś aby rozpakować je do innego (istniejącego) katalogu, wystarczy wpisać:

cabarc x archiwum.cab *.dll c:\windows\system\

Ostrzeżenie
Rozpakowując archiwa CAB, należy pamiętać o zakończeniu nazwy katalogu docelowego lewym ukośnikiem. Użycie w poprzednim przykładzie ścieżki c:\windows\system spowodowałoby umieszczenie rozpakowanych plików w katalogu bieżącym.

Samorozpakowujące się pliki CAB

Jak widać, tworzenie plików CAB i ich rozpakowywanie jest w zasadzie banalne, o ile tylko mamy do dyspozycji odpowiednie narzędzie (czyli program CABARC). Co jednak zrobić, gdy chcemy rozpowszechnić zestaw plików w postaci archiwum CAB dostępnego poprzez Internet? Trudno w końcu wymagać od użytkowników, by pobierali odpowiednie narzędzia ze stron Microsoftu, instalowali je i uczyli się ich obsługi. Na szczęście istnieje inne rozwiązanie - wystarczy wyposażyć archiwum CAB w możliwość samodzielnego rozpakowania. Nic prostszego:

copy /b extract.exe+archiwum.cab archiwum.exe

Uruchomienie tak utworzonego pliku archiwum.exe spowoduje automatyczne rozpakowanie zawartych w nim plików.

Pliki INF

Pliki w formacie INF (ang. information file - plik informacji instalacyjnych lub skrypt instalacyjny) są zwykłymi plikami tekstowymi, zawierającymi dyrektywy sterujące instalacją sterowników, programów użytkowych, komponentów przeglądarek i innego oprogramowania. Zawartość pliku INF może być bardzo złożona (np. instalacja obszernego zestawu sterowników) lub banalnie prosta (np. uzupełnienie wpisu w rejestrze).

Struktura pliku INF przypomina znane użytkownikom Windows pliki INI. Treść pliku podzielona jest na sekcje, te zaś zawierają dyrektywy zarządzające kopiowaniem plików, instalowaniem sterowników i innymi operacjami. Omówieniu dyrektyw poświęcimy kolejny punkt.

Ostrzeżenie
Plików INF nie należy mylić z plikami INI. Co prawda oba rodzaje plików wykorzystują podobną składnię, lecz przeznaczenie danych zawartych w plikach INI jest inne - definiują one informacje konfiguracyjne, sterujące działaniem aplikacji.

Sekcje i dyrektywy w plikach INF

Sekcje pliku INF identyfikowane są nazwami, a kolejność ich zapisu nie ma znaczenia. Nazwa sekcji zawarta jest w nawiasach kwadratowych i może zawierać do 28 znaków. Oto przykład:

[Strings]

Msg="Witamy"

Uwaga:
Wielkość liter w nazwie sekcji nie ma znaczenia. W przypadku wystąpienia w pliku kilku sekcji o tej samej nazwie, ich zawartość łączona jest w jedną całość.

Najczęściej wykorzystywane w plikach INF nazwy sekcji i dyrektywy opisano w tabelach 18 --> .2.i 18.3[Author:ts] .

Tabela 18.2. Nazwy sekcji używane w plikach INF

Nazwa

Przeznaczenie zawartości

ClassInstall32

Instalowanie nowych klas urządzeń (zapis odpowiednich danych w rejestrze)

ControlFlags

Sterowanie sposobem instalowania urządzenia za pomocą Kreatora dodawania nowego sprzętu

DestinationDirs

Ustalanie docelowej lokalizacji kopiowanych plików

InterfaceInstall32

--> Instalowanie klas interfejsów urządzeń (zapis odpowiednich danych w rejestrze)[Author:ts]

Manufacturer

Identyfikacja producenta urządzenia

SourceDisksFiles

Ustalanie źródłowej lokalizacji kopiowanych plików

SourceDisksNames

Ustalanie nazw identyfikujących dyski źródłowe

Strings

Definiowanie łańcuchów tekstowych używanych podczas instalacji (np. dla różnych wersji językowych)

Tabela 18.3. Dyrektywy używane w plikach INF

Dyrektywa

Przeznaczenie

AddInterface

Instalowanie obsługi interfejsów urządzeń

AddReg

Modyfikowanie wpisów w rejestrze systemowym

AddService

Instalowanie usług systemowych

BitReg

Ustalanie wartości binarnych kluczy rejestru

CopyFiles

Kopiowanie plików z dysków instalacyjnych do katalogu docelowego

DelFiles

Usuwanie plików z katalogu docelowego

DelReg

Usuwanie wpisów z rejestru

DelService

Usuwanie usług systemowych

Ini2Reg

Kopiowanie wpisów konfiguracyjnych z plików INI do rejestru

LogConfig

Definiowanie sekcji pliku INF zawierających zestawy parametrów konfiguracyjnych

RenFiles

Zmiana nazw plików w katalogu docelowym

UpdateIniFields

Definiowanie sekcji zawierających dyrektywy zmiany fragmentów wpisów w plikach INI

UpdateInis

Definiowanie sekcji zawierających dyrektywy zmiany całych wpisów w plikach INI

Przedstawione tu nazwy sekcji i dyrektywy to zaledwie fragment dostępnych możliwości. Szczegółowe informacje na temat składni plików INF można znaleźć w dokumentacji pakietu Windows Driver Development Kit (DDK), dostępnej pod adresem http://www.microsoft.com/ddk/.

Wskazówka
W plikach INF można także umieszczać komentarze. Komentarzem jest każdy ciąg znaków, następujący po znaku średnika, o ile nie został ujęty w znaki cudzysłowu (").

Tworzenie plików INF

Spróbujmy obecnie utworzyć przykładowy plik INF (gotową postać pliku, test.inf, można znaleźć w katalogu INF Files na dołączonej do książki płycie CD-ROM). Jak powiedzieliśmy wcześniej, plik INF jest zwykłym plikiem tekstowym, toteż można go utworzyć za pomocą dowolnego edytora - w tym także edytora kodu C++Buildera. Jeśli zdecydujesz się na użycie tej metody, uruchom IDE, wybierz polecenie New z menu File i w oknie dialogowym New Items kliknij ikonę Text. Utworzony plik zapisz pod nazwą test.inf.

Tworzony w naszym przykładzie plik powinien realizować następujące zadania:

Jak zapewne wszyscy się już domyślają, do wykonania pierwszego etapu należy użyć dyrektywy CopyFiles. Jej składnia jest następująca:

CopyFiles=@nazwa-pliku | sekcja-nazw-plików[, sekcja-nazw-plików ...]

W celu skopiowania pojedynczego pliku wystarczy podać jego nazwę poprzedzoną znakiem @. Jeśli mamy do czynienia z większą grupą plików, należy utworzyć w pliku INF nową sekcję, umieścić w niej nazwy żądanych plików, a jej nazwę wpisać jako argument dyrektywy CopyFiles. Powinno to wyglądać mniej więcej tak:

CopyFiles=Test.Copy

...

[Test.Copy]

Program.exe

Program.txt

Niestety, okazuje się, że brak tu jeszcze pewnej ważnej informacji - położenia katalogu źródłowego i docelowego. Do określenia tych parametrów służą opisane w tabeli 18.1 dyrektywy DestinationDirs, SourceDisksNames i SourceDisksFiles.

[DestinationDirs]

Test.Copy=10

[SourceDisksNames]

1="Dysk instalacyjny 1",,,,

[SourceDisksFiles]

Program.exe=1

Program.txt=1

Uwaga
Do określenia lokalizacji katalogu docelowego można użyć jednej z predefiniowanych wartości, np. 24 (katalog główny dysku zawierającego katalog --> Windows[Author:ts] ), 11 (katalog System), 30 (katalog główny dysku startowego) itd. W powyższym przykładzie użyto wartości 10, oznaczającej katalog Windows. Opis poszczególnych wartości można znaleźć w dokumentacji DDK.
Na przykład w celu utworzenia na dysku startowym (zwykle C:) folderu o nazwie MojProgram należałoby użyć zapisu:

Test.Copy=30,"MojProgram"

Aby nakazać automatyczne uruchomienie naszego programu wraz z rozpoczęciem pracy systemu operacyjnego, należy dopisać ścieżkę do pliku program.exe do klucza rejestru HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. Służy do tego dyrektywa AddReg:

AddReg=sekcja-wpisów[, sekcja-wpisów ...]

gdzie sekcja-wpisów identyfikuje sekcję pliku INF o następującej postaci:

[sekcja-wpisów]

klucz-główny,[podklucz],[nazwa],[opcje],[wartość]

Parametr klucz-główny to skrótowy identyfikator jednego z głównych kluczy rejestru. Jego możliwe wartości przedstawiono w tabeli 18.4.

Tabela 18.4. Identyfikatory głównego klucza rejestru

Identyfikator

Klucz rejestru

HKCR

HKEY_CLASSES_ROOT

HKCU

HKEY_CURRENT_USER

HKLM

HKEY_LOCAL_MACHINE

HKU

HKEY_USERS

Parametry podklucz i nazwa uzupełniają klucz główny, określając wraz z nim dokładne położenie modyfikowanego wpisu. Oto przykład zastosowania dyrektywy AddReg:

AddReg=Test.Reg

[Test.Reg]

HKLM,"Software\Microsoft\Windows\CurrentVersion\Run","ProgramTestowy",,"%10%\Program.exe"

Warto zwrócić uwagę na zapis identyfikatora katalogu docelowego (10). Użycie znaków procentu powoduje jego rozwinięcie do właściwej nazwy (w tym przypadku Windows).

Do kompletu brakuje jeszcze dwóch sekcji. Pierwsza, [Version], zawiera sygnaturę platformy docelowej. Domyślna wartość sygnatury, $CHICAGO$, oznacza system Windows 95 („Chicago” to jego dawny kryptonim), co oczywiście nie wyklucza możliwości użycia skryptu w innych 32-bitowych odmianach Windows (np. Windows NT). Druga sekcja, DefaultInstall, jest najważniejszym elementem skryptu, bowiem to właśnie ona zawiera polecenia wykonywane w czasie instalacji. Pełną zawartość przykładowego pliku INF przedstawiono na wydruku 18. --> 1[Author:ts] .

Wydruk 18.1. Kompletny skrypt instalacyjny TEST.INF

[Version]

Signature="$CHICAGO$"

[DefaultInstall]

AddReg=Test.Reg

CopyFiles=Test.Copy

[Test.Copy]

Program.exe

Program.txt

[DestinationDirs]

Test.Copy=10

[SourceDisksNames]

1="Dysk instalacyjny 1",Test,,,

[SourceDisksFiles]

Program.exe=1

Program.txt=1

[Test.Reg]

HKLM,"Software\Microsoft\Windows\CurrentVersion\Run","ProgramTestowy",,"%10%\Program.exe"

Aby sprawdzić jego działanie, skopiuj go wraz z testowymi plikami PROGRAM.EXE i PROGRAM.TXT na dyskietkę (lub do głównego katalogu dysku twardego, np. D:\). Kliknij ikonę pliku prawym przyciskiem myszy i wybierz z menu kontekstowego polecenie Instaluj. Rysunek 18.2 przedstawia zawartość rejestru po wykonaniu instalacji; jak widać, nazwa naszego programu została dopisana do klucza HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run.

Rysunek 18.2. Zawartość rejestru uzupełniona o nowy wpis po wykonaniu instalacji

Internetowe pakiety instalacyjne

Załóżmy, że właśnie napisaliśmy komponent ActiveX i chcielibyśmy udostępnić go przez Internet. Z punktu widzenia użytkownika najwygodniej byłoby po prostu otworzyć odpowiednią stronę WWW i pozwolić systemowi automatycznie zainstalować oprogramowanie. Możliwość taką dają internetowe pakiety instalacyjne - rozwiązanie zaproponowane przez firmę Microsoft, łączące w sobie możliwości archiwów CAB i skryptów instalacyjnych INF. Zasada działania pakietu jest prosta - wszystkie elementy aplikacji pakowane są do postaci pliku (lub plików) CAB, zaś stowarzyszony z nim plik INF zawiera polecenia informujące przeglądarkę o lokalizacji archiwów i sposobie instalowania ich zawartości.

Uwaga
W chwili pisania książki internetowe pakiety instalacyjne obsługiwane były tylko przez przeglądarki Internet Explorer w wersjach 3.0 i nowszych.

Zasada działania pakietu internetowego

--> Dostępne w pakiecie C++Builder narzędzia dystrybucji internetowej (Web Deploy) i ich wykorzystanie do dystrybucji komponentów ActiveX oraz formularzy omówiono już w rozdziale 22. Bogatsi o wiedzę na temat plików CAB i INF, możemy obecnie wrócić do wspomnianych narzędzi i zastanowić się nad zasadami działania pakietów internetowych. Jako przykład posłuży nam niewielki formularz ActiveForm, przedstawiony na rysunku 29.3. [Author:ts]

Bogatsi o wiedzę na temat plików CAB i INF, możemy obecnie zająć się narzędziami dystrybucji internetowej (Web Deploy) i zastanowić się nad zasadami działania pakietów internetowych. Jako przykład posłuży nam niewielki formularz ActiveForm, przedstawiony na rysunku 18.3.

Rysunek 18.3. Przykładowy formularz ActiveForm wyświetlany w przeglądarce Internet Explorer

W pierwszej kolejności zajmiemy się sposobem umieszczania zawartych w pakiecie komponentów ActiveX na stronie WWW. Kod testowego dokumentu HTML wygenerowanego automatycznie poleceniem Web Deploy przedstawiono na wydruku 18.2.

Wydruk 18.2. Dokument ActiveFormProj1.htm

<HTML>

<H1> C++Builder 5 ActiveX Test Page </H1><p>

You should see your C++Builder 5 forms or controls embedded in the form below.

<HR><center><P>

<OBJECT

classid="clsid:EDE8CA15-4DC2-4E0D-95FE-F7974DAEFC42"

codebase="d:/temp/ActiveFormProj1.inf"

width=257

height=171

align=center

hspace=0

vspace=0

>

</OBJECT>

</HTML>

Komponenty ActiveX umieszcza się w dokumentach HTML za pomocą znacznika OBJECT. Oprócz parametrów ustalających rozmiary i położenie komponentu posiada on dwa bardzo ważne atrybuty o nazwach CLASSID i CODEBASE. Pierwszy z nich, CLASSID, określa identyfikator klasy użyty do zarejestrowania obiektu (komponentu) w rejestrze Windows. Atrybut CODEBASE określa położenie (oraz opcjonalnie wersję) pliku zawierającego kod obiektu.

Jak widać na wydruku 18.2, wartością atrybutu CODEBASE jest ścieżka do pliku INF. W razie potrzeby można tu oczywiście używać innych plików - jeśli np. komponent nie wymaga instalowania żadnych dodatkowych składników, atrybut CODEBASE może odwoływać się doń bezpośrednio:

codebase="C:\WINDOWS\Temp\ActiveFormProj1.ocx#version=1,0,0,0"

Jeszcze lepszym rozwiązaniem jest użycie w tym miejscu nazwy pliku CAB, zawierającego składniki instalowanego komponentu (właściwy plik ActiveX, dodatkowe biblioteki itd.) oraz skrypt instalacyjny INF. Oto przykład:

codebase="C:\WINDOWS\Temp\ActiveFormProj1.cab#version=1,0,0,0"

Gwoździem programu jest oczywiście plik INF (również generowany automatycznie), sterujący procesem instalacji. Oto jego zawartość:

Wydruk 18.3. Plik ActiveFormProj1.inf

;C++Builder-generated INF file for ActiveFormProj1.ocx

[Add.Code]

ActiveFormProj1.ocx=ActiveFormProj1.ocx

VCL50.bpl=VCL50.bpl

[ActiveFormProj1.ocx]

file=D:/temp/ActiveFormProj1.cab

clsid={EDE8CA15-4DC2-4E0D-95FE-F7974DAEFC42}

RegisterServer=yes

FileVersion=1,0,0,0

[VCL50.bpl]

file=

FileVersion=5,0,6,18

DestDir=11

Jak widać, nie ma tu żadnych tajemnic. Cała zawartość pliku INF jest de facto wykazem instalowanych plików, opisanych w oddzielnych sekcjach. Każda sekcja zawiera informację o położeniu odpowiedniego pliku CAB, jego wersji oraz katalogu docelowym. Dla pliku VCL50.bpl identyfikator katalogu docelowego wynosi 11, co, jak powiedziano wcześniej, oznacza katalog Windows\System.

Wersje, uaktualnienia i poprawki

W podrozdziale tym zajmiemy się zagadnieniami kontroli wersji oraz uaktualnieniami i poprawkami. Pojęcia te wiążą się z modernizacją zainstalowanego oprogramowania oraz mechanizmami łatwego aktualizowania aplikacji i usuwania wykrytych i poprawionych przez producenta błędów.

Kontrola wersji

Kontrola wersji (ang. version control) jest niezwykle istotnym elementem procesu projektowego. Znajomość numeru wersji aplikacji daje użytkownikom orientację w jej możliwościach i ułatwia dokonywanie aktualizacji. Jest ona również istotna w przypadku udzielania pomocy technicznej i usuwania usterek - może się np. okazać, że wersja wykorzystywana przez użytkownika zawiera usterkę usuniętą w wersji późniejszej lub nie dysponuje funkcją, którą wprowadzono w kolejnym wydaniu.

Kontrola wersji w praktyce

W najprostszym przypadku numer wersji aplikacji wystarczy po prostu wpisać w oknie wizytówki, co jednak nie daje zbyt wielu możliwości (oprócz umożliwienia odczytania numeru wersji przez użytkownika). Można też użyć w tym celu jednego z komponentów umożliwiających wyświetlenie informacji o wersji na żądanie użytkownika, dostarczanych przez firmy trzecie.

Znacznie lepszym sposobem okazuje się wykorzystanie odpowiedniej funkcji samego C++Buildera. W oknie opcji projektu, wyświetlanym poleceniem Options z menu Project, znajduje się karta Version info, pozwalająca na zdefiniowanie informacji o wersji oraz umieszczenie jej w kodzie aplikacji. Ustalany tu numer wersji składa się z czterech części - numeru głównego (ang. major version number), pobocznego (minor version number), numeru wydania (release number) oraz numeru kolejnej kompilacji (build number). Zaznaczenie pola wyboru Auto-increment build number pozwala ponadto na automatyczną aktualizację ostatniego członu po każdej kompilacji. Pozostałe elementy karty Version info umożliwiają wpisanie dodatkowych informacji o programie, jak: opis, nazwa firmy oraz nota o prawach autorskich. Informacje te można znaleźć na karcie Wersja okna właściwości programu (wyświetlanego poprzez kliknięcie ikony programu prawym przyciskiem myszy i wybranie z menu polecenia Właściwości).

Ponieważ wyświetlenie okna właściwości programu wymaga nieco zachodu (wyszukanie ikony programu w Eksploratorze i kilka kliknięć), można ułatwić użytkownikowi zadanie, umieszczając numer wersji na wizytówce programu. W najprostszym przypadku robi się to ręcznie, wstawiając do formularza wizytówki etykietę o treści np.

Uniwersalny Program do Wszystkiego

Wersja 1.1

Przed utworzeniem kolejnej wersji wystarczy zmienić drugi wiersz na Wersja 1.2 i tak dalej. Użycie bardziej rozbudowanego numeru wersji pozwala na precyzyjniejsze określenie rodzaju dokonanej zmiany. Jeśli np. w programie

Uniwersalny Program do Wszystkiego

Wersja 1.1.0.0

wykryjemy i usuniemy jakiś błąd, wystarczy zwiększyć o jeden ostatni element numeru wersji:

Uniwersalny Program do Wszystkiego

Wersja 1.1.0.1

Wprowadzenie takiego podziału pozwala łatwiej zapanować nad dokumentacją i nazewnictwem (co oznacza mniejszy nakład pracy na tworzenie i aktualizację dokumentacji), a jednocześnie daje użytkownikom dokładniejszą informację o programie (na przykład zmiana ostatniej cyfry oznacza jedynie poprawkę, a nie wprowadzenie nowej funkcji).

Oprócz właściwego i konsekwentnego schematu numerowania bardzo istotnym elementem kontroli wersji jest dziennik zmian. Na ogół wystarczy do tego celu zwykły plik tekstowy przechowywany w katalogu macierzystym projektu i zawierający wpisy złożone z numeru wersji i opisu wprowadzonych modyfikacji. Oto przykład:

1.1.0.0 Pierwsza wersja oficjalna

--------

1.1.0.1 Usunięcie błędu w wyświetlaniu nazwy pliku

--------

1.2.0.0 Zmiana logo programu

Solidny dziennik zmian, zawierający informacje o wszystkich dokonanych modyfikacjach i poprawkach, pozwala w razie potrzeby odtworzyć historię projektu, nieoceniony zaś okazuje się w przypadku dyskusji z użytkownikiem zgłaszającym błąd w działaniu aplikacji.

Uaktualnienia

Program komputerowy, jak większość wytworów nowoczesnej technologii, nie jest tworem statycznym i podlega ciągłym modyfikacjom i rozszerzeniom. W niniejszym punkcie przedstawimy kilka sposobów wprowadzania modyfikacji i rozpowszechniania zaktualizowanych wersji oprogramowania, czyli tzw. uaktualnień (ang. update).

Co to jest uaktualnienie?

Z formalnego punktu widzenia jakakolwiek zmiana dokonana w aplikacji stanowi jej aktualizację. W praktyce jednak nie każda aktualizacja dokonana wewnętrznie kwalifikuje się do upublicznienia w postaci nowej wersji - może się okazać, że lepiej będzie poczekać na skumulowanie się kilku modyfikacji i przekazać użytkownikom wersję oferującą więcej nowych możliwości. Z oczywistych względów trudno tu podać jednoznaczne i oczywiste kryteria udostępniania zaktualizowanych wersji oprogramowania; przykładem zmiany wymagającej możliwie natychmiastowej reakcji jest wykrycie i usunięcie poważnego błędu, zanim przysporzy on kłopotów innym. Innym problemem, który należy rozważyć, jest sposób powiadamiania użytkowników o dostępności uaktualnienia.

Powiadamianie o uaktualnieniach

W przypadku programów udostępnianych na zasadzie licencji shareware (lub rejestrowanych na drodze elektronicznej) powiadamianie o uaktualnieniach jest stosunkowo proste, bowiem dane o zarejestrowanych użytkownikach wystarczy na ogół pobrać z bazy rejestracyjnej i wykorzystać do rozesłania powiadomień pocztą elektroniczną. To ostatnie zadanie można zrealizować za pomocą wyspecjalizowanego programu lub komponentu, ewentualnie poprzez standardowy program do obsługi poczty elektronicznej. Rozwiązanie pierwsze (na dłuższą metę prostsze i skuteczniejsze) sprowadza się do utworzenia prostej bazy danych wyposażonej w komponent wysyłający pocztę elektroniczną i umożliwiający grupową dystrybucję wiadomości. Przykładowa aplikacja może zawierać np. --> tabelę [Author:ts] klientów oraz drugą tabelę, zawierającą informacje o zarejestrowanych przez nich aplikacjach, datach rejestracji, kodach dostępu itp. Do zredagowania tekstu wiadomości można wykorzystać komponent TMemo, zaś do ich wysyłania zatrudnić komponent --> TSMTP[Author:ts] lub jeden z dostarczanych przez firmy trzecie komponentów pozwalających przekazać wiadomość za pośrednictwem zewnętrznego programu do obsługi poczty elektronicznej. Przykładem może tu być np. używany przez autora komponent autorstwa firmy AHM Triton Tools (http://www.tritontools.com) lub liczne dostępne bezpłatnie komponenty wykorzystujące zewnętrzne programy klientów MAPI lub SMTP, jak np. komponent TEmail, dostępny pod adresem http://www.econos.de (w chwili wydawania polskiego przekładu nie był on dostępny w wersji dla C++Buildera 5).

Sam proces rozesłania powiadomień sprowadza się do przeszukania tabeli klientów, pobrania adresów poczty elektronicznej z poszczególnych rekordów, odczytania zawartości pola TMemo i wysłania tak skomponowanych wiadomości. Gdyby to samo chcieć zrealizować „ręcznie”, należałoby wpisać adresy poszczególnych klientów do pola DW: (CC:) lub też (co jest rozwiązaniem znacznie lepszym ze względu na ochronę poszczególnych adresów przed oczami innych) pola UDW: (BCC:).

Alternatywną metodą wykorzystania poczty elektronicznej jest usługa ListBot (http://www.listbot.com) lub jeden z pokrewnych serwisów, umożliwiających automatyczne rozsyłanie poczty do użytkowników zarejestrowanych na liście dystrybucyjnej. Rozwiązanie to ma jednak tę wadę, iż zmusza użytkownika do dodatkowej rejestracji na liście prowadzonej w serwisie ListBot. Trzecim sposobem jest wreszcie opublikowanie wiadomości o uaktualnieniu na widocznym miejscu firmowej witryny WWW (o ile taką posiadamy). Również i tu jednak problemem pozostaje „pasywność” takiego rozwiązania - dopóki klient nie zajrzy na naszą stronę, nie będzie miał pojęcia, że pojawiła się nowa wersja programu. Jedynym w miarę pewnym sposobem dotarcia do każdego zarejestrowanego użytkownika jest bezpośrednie wysłanie doń wiadomości.

Udostępnianie uaktualnień

Po dokonaniu odpowiednich zmian i ustaleniu sposobu dystrybucji należy wybrać formę, w jakiej uaktualnienie zostanie przekazane użytkownikom. Może to być plik zawierający tylko poprawki, można też udostępnić kompletny pakiet instalacyjny, zastępujący poprzednią wersję.

Poprawki czy wersja pełna?

Udostępnienie zaktualizowanej wersji aplikacji w postaci pełnego pakietu instalacyjnego okazuje się często najlepszym rozwiązaniem. W takiej sytuacji należy zadbać, by pliki kopiowane podczas instalacji zastąpiły poprzednie składniki, obecne już w systemie docelowym.

Warto pamiętać, że odbiorca uaktualnienia ma już na ogół za sobą kontakt z poprzednią wersją programu instalacyjnego, co zmniejsza nieco stres związany z obsługą nowej aplikacji. Jednym z pospolitszych grzechów projektantów oprogramowania jest ignorowanie niewiedzy innych i zakładanie, że przeciętny Kowalski wie o komputerach tyle samo, co autor programu. Dlatego też przygotowując program instalacyjny, należy zawsze postawić się „po drugiej stronie barykady” i spojrzeć na swoje dzieło oczami niedoświadczonego użytkownika.

Poprawki

Poprawki (ang. patch) stanowią alternatywną metodę aktualizowania oprogramowania. W odróżnieniu od „pełnego” uaktualnienia użycie poprawki sprowadza się do programowego „nałożenia łat”, czyli zmiany fragmentów jednego lub kilku plików bez naruszania istniejącej instalacji.

Utworzenie poprawki wymaga porównania pierwotnej wersji kodu --> wynikowego [Author:ts] z wersją zmodyfikowaną, a następnie zapisaniu różnic w pliku. Ostatnim etapem jest wygenerowanie skryptu „nakładającego łaty”, czyli zmieniającego odpowiednie fragmenty kodu znajdującego się w systemie docelowym.

Jednym z lepszych narzędzi służących do tworzenia poprawek jest Patch Maker wspomnianej już wcześniej firmy ClickTeam. Jest on dostępny w dwóch wersjach, komercyjnej i freeware, przy czym tę ostatnią można pobrać z witryny internetowej producenta (http://www.clickteam.com) lub skopiować z dołączonej do książki płyty CD-ROM.

Tworzenie pliku poprawki

Po podjęciu decyzji o udostępnieniu nowej wersji w postaci poprawki należy przygotować odpowiedni plik i przekazać go użytkownikom. Do utworzenia pliku poprawki z powodzeniem nadaje się wersja freeware programu Patch Maker, którą omówimy za chwilę. Przygotowany w ten sposób program najpierw sprawdza zgodność numerów wersji, a następnie modyfikuje fragmenty odpowiednich plików, aktualizując je w ten sposób do nowej wersji. Kontrola wersji jest w tym przypadku szczególnie istotna, gdyż (z dość oczywistych względów) poprawka daje się skutecznie (i bezpiecznie) zastosować tylko dla wersji, dla której została przygotowana. Załóżmy np., że aplikacja dostępna jest w trzech kolejnych wersjach:

1.0 - pierwsza wersja oficjalna,

1.1 - wersja poprawiona (poprzez usunięcie błędów),

1.2 - wersja zmodernizowana,

zaś poprawkę przygotowano w celu zaktualizowania wersji 1.1 do 1.2. Próba użycia jej dla programu w wersji 1.0 zakończy się błędem i zaniechaniem aktualizacji, bowiem wprowadzenie modyfikacji spowodowałoby najprawdopodobniej zmianę niewłaściwych fragmentów kodu.

Program Patch Maker

Po zainstalowaniu programu Patch Maker, a przed wygenerowaniem pliku poprawki, niezbędne jest wykonanie kilku czynności przygotowawczych. Przede wszystkim należy utworzyć dwa oddzielne katalogi, w których muszą znaleźć się odpowiednio oryginalny plik programu (wersja przed modyfikacją) i plik poprawiony (wersja po modyfikacji). Etap ten jest konieczny, gdyż Patch Maker wymaga istnienia obu katalogów w trakcie tworzenia pliku poprawki.

Co prawda Patch Maker jest w stanie utworzyć zbiór poprawek przeznaczony dla kilku plików, jednak w praktyce rzadko modyfikuje się więcej niż jeden plik naraz. Dlatego też w naszym opisie poprzestaniemy na przygotowaniu poprawki dla pojedynczego pliku (chociaż nic nie stoi na przeszkodzie, by poeksperymentować na własną rękę).

Po utworzeniu nowej wersji aplikacji uruchom program Patch Maker. Na ekranie pojawi się okno kreatora Patch Wizard.

  1. Okno powitalne

Po uruchomieniu programu Patch Maker wyświetlane jest okno powitalne. Umożliwia ono zrezygnowanie z usług kreatora i przejście bezpośrednio do głównego okna programu, jednak nowicjuszom zaleca się pozostanie w trybie kreatora, który umożliwia łatwiejsze zapoznanie się z podstawowymi funkcjami programu.

  1. Ustalenie katalogów źródłowych --> [Author:ts]

W kolejnym kroku określa się położenie katalogów, zawierających poprzednią wersję aplikacji (przed zmianami) oraz wersję po modyfikacjach. Ponieważ w polach edycyjnych wpisuje się nazwy katalogów, a nie pojedynczych plików, możliwe jest utworzenie zbioru poprawek dla więcej niż jednego pliku. Widoczne w dolnej części okna pole wyboru Include sub-directories pozwala przeszukiwać również podkatalogi. Ma to sens tylko w razie przetwarzania wielu plików, toteż w naszym przypadku opcję tę należy wyłączyć.

  1. Ustalenie tytułu aplikacji i języka programu instalacyjnego

Następne okno kreatora pozwala wybrać język programu instalującego poprawkę (angielski lub francuski) oraz ustalić jego „długą” nazwę (będzie ona wyświetlana w głównym oknie programu, a także w lewym górnym rogu ekranu, o ile nie zostanie zmieniona w kroku 5.). Zwykle używa się tu nazwy modyfikowanego programu, uzupełnionej ewentualnie numerem wersji. Kliknięcie przycisku Preview pozwala sprawdzić, jak będzie się prezentował ekran tworzonej aplikacji.

  1. Informacje dodatkowe

Okno wyświetlane w kolejnym kroku pozwala wpisać krótki tekst, zawierający np. informację o wprowadzanych poprawkach. Tekstu nie da się co prawda odczytać z pliku, jednak w razie potrzeby można wkleić do okna zawartość schowka. Po wpisaniu i sformatowaniu tekstu warto obejrzeć końcowy wygląd okna, klikając przycisk Preview.

  1. Definiowanie ustawień ekranu i okna instalatora

W następnym etapie ustala się wygląd ekranu roboczego programu (praca w zwykłym oknie lub pełnoekranowa) oraz nazwę wyświetlaną w lewym górnym rogu ekranu.

  1. Wybór obrazków

Kolejne okno kreatora pozwala wybrać obrazek wyświetlany w lewej części okna programu instalacyjnego oraz mapę bitową zastępującą standardowe tło w przypadku pracy pełnoekranowej. Należy przy tym pamiętać, że użycie dodatkowych obrazków powiększa rozmiar tworzonego pliku.

Mapa bitowa wyświetlana w lewej części każdego z okien programu musi być zapisana w postaci pliku BMP, mieć określone wymiary (128 na 280 pikseli) i co najwyżej 256 kolorów. Druga mapa, używana jako „tapeta” w trybie pełnoekranowym, również musi pochodzić z pliku BMP i zawierać nie więcej niż 256 kolorów, może natomiast mieć dowolne wymiary, bowiem jest rozkładana na całej powierzchni ekranu. Wygląd ekranu po wybraniu obrazków można podejrzeć, klikając przycisk Preview.

  1. Ustalenie katalogu docelowego

Okno Installation directory umożliwia ustalenie lokalizacji modyfikowanego programu, tj. katalogu zawierającego poprzednią wersję (np. C:\Program Files\Firma\JakisProgram). Należy pamiętać, że plik poprawek musi znajdować się w tym samym katalogu, co modyfikowana aplikacja, w przeciwnym razie nasz program nie będzie miał czego modyfikować i zakończy działanie z komunikatem Nothing to do (Nie ma nic do zrobienia). Nie od rzeczy będzie także poinformowanie użytkownika o wymaganej lokalizacji pliku.

W razie potrzeby można też nakazać instalatorowi odczytanie nazwy katalogu docelowego z rejestru lub pliku INI. Kliknięcie przycisku Registry base wyświetla okno umożliwiające określenie położenia danych w rejestrze, zaś przycisk INI file pozwala podać informacje lokalizujące nazwę katalogu w wybranym pliku INI.

  1. Ustawienia końcowe

Ostatnie okno kreatora zawiera tylko jedną opcję, której zaznaczenie zabrania utworzenia pliku poprawek. Jeżeli wszystkie dane wprowadzone w poprzednich krokach są prawidłowe, nie pozostaje nam nic innego, jak kliknąć przycisk Dalej i wygenerować plik. W razie wątpliwości można cofnąć się do poprzednich kroków, klikając przycisk Wstecz.

  1. Utworzenie pliku poprawek

Kliknięcie przycisku Dalej wyświetla okno zapisania pliku, umożliwiające podanie nazwy i lokalizacji tworzonego pliku poprawek. Docelowa lokalizacja pliku może być dowolna, z jednym ograniczeniem - nie należy umieszczać go w katalogach zawierających porównywane wersje aplikacji (ani ich podkatalogach), bowiem może zostać wzięty pod uwagę przy tworzeniu kolejnych poprawek. Po utworzeniu pliku warto zachować całość projektu (skrypt zapisywany jest w pliku o rozszerzeniu .uts) na potrzeby przyszłych modyfikacji.

Aby sprawdzić działanie utworzonego programu, najlepiej uruchomić go tak, jak zrobi to użytkownik, czyli np. z okna Eksploratora Windows, pamiętając przy tym, iż plik poprawek musi znajdować się w tym samym katalogu, co modyfikowana aplikacja (położenie katalogu ustala się w kroku 7. kreatora). Po „nałożeniu łat” należy oczywiście sprawdzić skuteczność tego procesu, uruchamiając poprawioną aplikację. Jeśli efekty zmian nie są widoczne „gołym okiem” (modyfikacje polegają np. na usunięciu błędu w obliczeniach), weryfikacji można dokonać poprzez sprawdzenie numeru wersji.

Wskazówki odnośnie uaktualnień i poprawek

Decydując się na udostępnienie uaktualnienia bądź poprawki, warto pamiętać o kilku praktycznych wskazówkach.

System kontroli wersji TeamSource

Wszelkie zmiany dokonywane w danych powodują utratę poprzednich informacji. Poszczególne wersje kodu źródłowego można traktować jako „obrazy” pewnego zmiennego procesu (projektowania aplikacji) uchwycone w określonych momentach. Mówiąc najprościej, systemy kontroli wersji pozwalają na przechowywanie i zarządzanie obrazami stanu procesu projektowego. W terminologii używanej w systemach kontroli wersji zapamiętanie takiego obrazu nosi nazwę umieszczenia projektu w archiwum lub repozytorium (ang. checking in the archive).

Kod źródłowy - najcenniejsze dane każdego programisty - zmienia się w procesie projektowania nieustannie. Zmiany te mogą przejawiać się w dodawaniu nowych elementów, jednak znacznie częściej sprowadzają się do usuwania fragmentów kodu i zastępowania ich innymi, a to oznacza utratę poprzednich zapisów. Właśnie w tym miejscu dochodzą do głosu systemy kontroli wersji, umożliwiające zachowanie starszych wersji plików źródłowych i zarządzanie nimi. W tym podrozdziale omówimy jeden z takich systemów - program TeamSource, wchodzący w skład pakietów C++Builder Enterprise i Delphi, a także dostępny w postaci samodzielnej aplikacji. Chociaż TeamSource sprawdza się najlepiej w połączeniu ze środowiskami programistycznymi firmy Borland (C++Builder i Delphi), można go również stosować do zarządzania innymi projektami, które dają się zamknąć w obrębie pojedynczego katalogu (i jego podkatalogów). Możliwości systemu TeamSource nie ograniczają się do zarządzania plikami tekstowymi - pozwala on również nadzorować tworzenie dokumentacji zapisanej w dokumentach Worda, witryn WWW złożonych z dokumentów HTML i plików graficznych (GIF, JPG) i tak dalej.

Dla kogo przeznaczony jest TeamSource?

Jak sama nazwa wskazuje, system TeamSource został stworzony z myślą o zespołach projektowych (ang. team). Nie oznacza to jednak, że nie mogą korzystać z niego również programiści pracujący w pojedynkę.

Dlaczego używać TeamSource?

W najprostszym przypadku TeamSource umożliwia projektantowi aplikacji zachowanie całej historii budowy projektu. Jaka stąd korzyść? Jeśli podczas pracy okaże się, że któraś z podjętych wcześniej decyzji przyniosła niewłaściwe efekty, można będzie wrócić do momentu jej wdrożenia i skorygować błąd. Daje to programiście większy komfort i swobodę podejmowania decyzji, minimalizując konsekwencje błędów popełnionych w procesie projektowania. Przyczyną powrotu do starszej wersji nie musi być zresztą błąd w planowaniu lub wykonaniu. Znacznie częściej okazuje się nią konieczność powrotu do starszej wersji oprogramowania, wykorzystywanej przez użytkownika, który zgłasza problemy z jego użytkowaniem, a jednocześnie z jakichś przyczyn nie chce lub nie może dokonać aktualizacji.

Możliwości systemu TeamSource obejmują także zarządzanie kilkoma równoległymi wersjami tego samego projektu. Przykładem może tu być sytuacja, w której różne komórki zespołu projektowego pracują jednocześnie nad różnymi elementami tej samej aplikacji, np. aktualizacją struktury bazy danych (poprzez dodanie tabel) i zarządzającego nią mechanizmu (poprzez migrację do architektury klient-serwer). W przypadku „ręcznego” zarządzania projektem etapy te byłyby zapewne wykonywane jeden po drugim, natomiast użycie systemu kontroli wersji, takiego jak TeamSource, pozwala zrealizować je równocześnie i połączyć wyniki prac w jedną całość po ich dopracowaniu i przetestowaniu.

Niektóre projekty oprogramowania okazują się być na tyle złożone i obszerne, że trzeba je podzielić na elementy objęte niezależną kontrolą wersji. W skład projektu mogą np. wchodzić już dopracowane (a przez to bardziej „statyczne”) biblioteki oraz kod nowych aplikacji, podlegający nieustannej przebudowie i modyfikowany kilka razy dziennie.

Kiedy używać TeamSource?

Wykorzystanie systemu TeamSource powinno opierać się na przemyślanej strategii. W najprostszym wypadku pliki wchodzące w skład projektu należy archiwizować raz dziennie, po zakończeniu pracy nad nimi. Ponieważ dodawanie nowych elementów i funkcji zabiera zwykle więcej niż dzień, rejestracja dat rozpoczęcia i zakończenia takich etapów pozwala stosunkowo łatwo powrócić do poprzednich wersji.

Rozsądniejszą strategią jest zsynchronizowanie archiwizacji nie z kalendarzem, a z kolejnymi etapami pracy nad projektem. „Etapem” nazywamy tu cały cykl zmian, mających na celu dodanie lub zmianę określonej cechy aplikacji. Pojęcie „cechy” jest przy tym dość płynne i zwykle można je podzielić na kilka poziomów hierarchii zadań, jednak dla konkretnych projektów, realizowanych przez konkretne zespoły, daje się ono dość dobrze sprecyzować (na ogół pozwala to również na uściślenie poszczególnych zadań w hierarchii).

Gdzie można używać TeamSource?

Oprogramowanie TeamSource może być wykorzystywane zarówno na pojedynczym komputerze, jak i w sieci lokalnej. Można je z pewnym przybliżeniem traktować jako rozszerzenie narzędzia do archiwizacji kodu źródłowego, co narzuca odpowiednie wymagania na lokalizację archiwów - powinny one znajdować się na urządzeniu fizycznie wyodrębnionym i możliwie jak najbardziej odległym od komputera używanego do pracy nad kodem. Rozdzielenie takie jest w systemie TeamSource jak najbardziej możliwe.

O ile tylko prawidłowo opracujemy strategię archiwizowania plików, TeamSource może okazać się znacznie skuteczniejszym narzędziem archiwizującym niż standardowo wykorzystywane systemy tworzenia dziennych kopii zapasowych. W razie stwierdzenia błędu projektowego bardziej prawdopodobna jest konieczność powrotu do wersji „przed dodaniem jakiejś funkcji”, aniżeli „sprzed tygodnia”. Nie można oczywiście wykluczyć awarii katastrofalnych (np. uszkodzenia dysku serwera), kiedy to zależy nam na odtworzeniu stanu projektu na etapie możliwie jak najbardziej zbliżonym do momentu, w którym nastąpiła utrata danych. Jak widać, TeamSource jest czymś więcej niż tylko alternatywą dla konwencjonalnych systemów tworzenia kopii zapasowych.

Jak używać TeamSource?

Podobnie jak sam C++Builder, system TeamSource opiera się na koncepcji projektów, przy czym za projekt uznaje się tu zbiór plików zawartych w pojedynczym folderze (katalogu). Zależność od lokalizacji jest w przypadku TeamSource bardziej ścisła, niż ma to miejsce dla C++Buildera - projekt TeamSource może zawierać wyłącznie pliki zawarte w danym katalogu i jego podkatalogach, podczas gdy C++Builder pozwala na dołączenie do projektu plików zewnętrznych (np. wspólnych dla kilku projektów). Ograniczenie to może powodować konieczność reorganizacji struktury katalogów przed wprowadzeniem kontroli wersji za pomocą systemu TeamSource.

Utworzenie projektu

Utworzenie projektu w systemie TeamSource wymaga większego wysiłku niż późniejsze nim zarządzanie, jednak większy nakład pracy poświęcony na prawidłowe skonfigurowanie projektu procentuje w późniejszym użytkowaniu, a to z kolei pozwala na ściślejszy i pełniejszy nadzór nad realizowanymi projektami.

Przed rozpoczęciem pierwszej sesji TeamSource wymaga zidentyfikowania użytkownika poprzez podanie nazwiska i adresu poczty elektronicznej. Po wprowadzeniu tych informacji można już utworzyć nowy projekt za pomocą polecenia New Project z menu File. Wyświetla ono okno dialogowe, pozwalające utworzyć projekt od podstaw lub zaimportować projekt już istniejący.

Importowanie istniejącego projektu

Projektanci pracujący w pojedynkę na ogół tworzą projekty samodzielnie, natomiast w pracy zespołowej projekt tworzony jest przez jednego członka zespołu i udostępniany innym. Zaimportowanie wcześniej utworzonego projektu sprowadza się do wybrania go w oknie otwarcia pliku i określenia miejsca składowania go w systemie lokalnym (zobacz punkt „Ustalenie położenia katalogu lokalnego” w dalszej części rozdziału). Po wykonaniu tych czynności następuje skopiowanie plików projektu do katalogu lokalnego, którego zawartość będzie używana do aktualizacji projektu.

Tworzenie nowego projektu

Proces tworzenia nowego projektu składa się z następujących kroków:

Utworzenie projektu

Do utworzenia nowego projektu wykorzystywany jest kreator, realizujący tę procedurę w siedmiu etapach. Opisane w poniższych punktach okna dialogowe pozwalają wprowadzić wszystkie informacje definiujące postać projektu. Ich lista jest dość obszerna, ale wartości domyślne proponowane przez kreator okazują się w wielu przypadkach wystarczające.

  1. Opis tworzonego projektu. W kroku tym ustala się następujące informacje (wymagane):

  1. Położenie głównego folderu projektu. Folder ten zawiera pliki projektu wykorzystywane przez program TeamSource. Odpowiednią nazwę można wpisać z klawiatury lub ustalić, posługując się przyciskiem przeglądania folderów (...). Folder główny powinien się na ogół znajdować na innym komputerze (a przynajmniej na innym dysku) niż właściwy projekt C++Buildera. W przypadku pracy w sieci lokalnej folder główny umieszcza się na ogół na serwerze.

Ostrzeżenie
Użytkownicy korzystający z folderu projektu muszą posiadać odpowiednie prawa dostępu.

  1. Położenie folderów podrzędnych. W skład głównego folderu projektu wchodzą foldery Archive (archiwum poprzednich wersji), History (historia zapisów kolejnych wersji do archiwum) oraz Locks (pliki blokad, zabraniające użytkownikom jednoczesnego modyfikowania plików projektu). Podane tu nazwy domyślne można w razie potrzeby zmienić.

  2. Katalog zapasowy (lustrzany) projektu. TeamSource umożliwia stworzenie aktualizowanej na bieżąco kopii projektu, będącej dokładnym powieleniem wszystkich jego plików. Użycie tej opcji wymaga zaznaczenia pola wyboru Enable Mirror tree i określenia katalogu, w którym zostanie umieszczony folder z kopiami. Ten ostatni jest domyślnie lokowany w głównym folderze projektu, ale warto zmienić to ustawienie, umieszczając kopie zapasowe na oddzielnym dysku lub innym komputerze.

  3. Ustawienia publikacji danych o stanie projektu. Kolejne okno pozwala określić nazwę pliku, zawierającego komentarze do kolejnych wersji (ang. summary file), oraz pliku dziennika aktualizacji (ang. check-in log file), zawierającego szczegółowe informacje o kolejnych wersjach umieszczanych w archiwum (nazwa użytkownika dokonującego operacji, data operacji, lista plików zapisywanych w archiwum, komentarze). Pole SMTP Server umożliwia określenie serwera SMTP używanego do rozsyłania informacji o zmianach w projekcie drogą poczty elektronicznej.

  4. Adresy poczty elektronicznej. Jeśli w poprzednim kroku zdefiniowano nazwę serwera SMTP, wyświetlane jest okno pozwalające na wprowadzenie adresów e-mail osób, które mają być powiadamiane o zmianach w projekcie. Umieszczenie dowolnego elementu projektu w archiwum może powodować rozesłanie do określonej grupy użytkowników następujących informacji:

Adresatów wiadomości określa się poprzez wprowadzenie pojedynczych adresów lub ich list w odpowiednich polach okna.

  1. Zatwierdzenie konfiguracji. Ostatnie okno kreatora prezentuje podsumowanie wprowadzonych danych i umożliwia ich zweryfikowanie. W razie konieczności wprowadzenia zmian wystarczy powrócić do odpowiedniego kroku. Najistotniejszymi elementami, na które należy zwrócić uwagę, są:

Innymi słowy, do utworzenia prawidłowego projektu wystarczy zdefiniowanie powyższych ustawień i zaakceptowanie pozostałych wartości w postaci domyślnej. Programiści pracujący samodzielnie mogą ponadto pominąć elementy związane z powiadomieniami, czyli nazwę serwera SMTP i adresy poczty elektronicznej.

Ustalenie położenia katalogu lokalnego

Bezpośrednio po zakończeniu definiowania projektu TeamSource umożliwia określenie położenia katalogu lokalnego, zawierającego kopie plików źródłowych. Krok ten można pominąć (klikając przycisk Nie), jeśli np. pliki źródłowe znajdują się na innym komputerze (zobacz punkt „Katalogi lokalne” w dalszej części rozdziału), jednak na ogół udziela się w tym miejscu odpowiedzi twierdzącej. Powoduje to wyświetlenie okna służącego do zdefiniowania listy katalogów (poszczególne nazwy można wpisywać z klawiatury lub ustalać za pomocą przycisku przeglądania...). W przypadku zdefiniowania kilku katalogów, kopie plików projektu są umieszczane w każdym z nich.

Kolejnym etapem jest uruchomienie kreatora zawartości (Content Wizard), pozwalającego ustalić zawartość katalogów lokalnych. Również i tę operację można odłożyć na później, jednak na ogół wykonuje się ją od razu. Kreator zawartości przegląda katalogi lokalne i wyświetla drzewo wszystkich znajdujących się w nich plików i podkatalogów. Kliknięcie ikony podkatalogu rozwija odpowiednią gałąź drzewa i wyświetla listę rozszerzeń nazw plików zawartych w danym podkatalogu. Lista ta identyfikuje wszystkie pliki objęte kontrolą wersji i na ogół wymaga „przycięcia”, czyli usunięcia rozszerzeń plików pośrednich (.obj, *.il*), kopii zapasowych (.~cpp) i innych plików o charakterze tymczasowym (.tmp, .cgl itd.). Przycisk Delete Directory umożliwia usuwanie z drzewa całych katalogów, o ile nie zawierają one potrzebnych plików.

Po skonfigurowaniu lokalnych i zdalnych elementów projektu można powrócić do głównego okna programu TeamSource, prezentującego skrótowe zestawienie informacji o projekcie.

Opcje projektu

Użytkownik będący twórcą projektu, jest jednocześnie jego administratorem i posiada związane z tym uprawnienia. Przed przystąpieniem do korzystania z projektu warto poświęcić nieco czasu na zapoznanie się z opcjami sterującymi jego wykorzystaniem - o ile dla indywidualnego programisty jest to przydatne, w pracy zespołowej staje się niezbędne. W tym ostatnim przypadku konieczne jest ustalenie co najmniej jednej opcji - nazw użytkowników uprawnionych do korzystania z projektu.

Zmiana opcji projektu wymaga przede wszystkim jego zablokowania przez administratora (zobacz punkt „Ustanowienie blokady” w dalszej części rozdziału), a następnie wybrania polecenia Options z menu Project. Wyświetlone w ten sposób okno dialogowe zawiera cztery karty o nazwach General, Directories, Users i Publishing.

Karta General

Elementy zawarte na karcie General pozwalają zmienić następujące parametry:

Karta Directories

Karta Directories umożliwia zmianę położenia katalogów, zawierających pliki projektu (definiowane w trzecim i czwartym oknie dialogowym kreatora projektu, zobacz punkt „Utworzenie projektu” powyżej).

Karta Users

Karta Users zawiera listę użytkowników uprawnionych do dostępu do projektu. Przycisk Add User pozwala na dopisanie do listy nowego użytkownika i ustalenie jego praw dostępu. Te ostatnie mogą obejmować:

Wpisy na liście użytkowników można modyfikować (poprzez zmianę nazwy użytkownika i praw dostępu) oraz usuwać, jednak użytkownik nie może zmienić wpisu dotyczącego jego samego.

Wskazówka
Nazwa użytkownika w systemie TeamSource jest identyczna z nazwą zarejestrowaną w Windows.

W dolnej części karty Users znajduje się pole wyboru zatytułowane Allow Guest Access to This Project. Jego zaznaczenie udostępnia projekt wyłącznie do odczytu wszystkim użytkownikom. Warto tu zauważyć, że w przypadku utworzenia projektu przez użytkownika anonimowego (co jest możliwe w systemach Windows 9x), pełne uprawnienia administratora będzie miał każdy użytkownik, który nie zaloguje się w systemie.

Karta Publishing

Opcje dostępne na karcie Publishing zarządzają powiadamianiem użytkowników o zapisywanych w archiwum zmianach w projekcie. Ich znaczenie opisano podczas omawiania piątego i szóstego okna kreatora projektu (zobacz punkt „Utworzenie projektu”).

Katalogi lokalne

Używana w terminologii systemu TeamSource nazwa „katalog lokalny” (local directory) odnosi się w najprostszym przypadku do katalogu znajdującego się w lokalnym systemie plików i zawierającego pliki źródłowe projektu C++Buildera. Okazuje się jednak, iż w bardziej złożonych okolicznościach „katalog lokalny” może znajdować się na innym komputerze lub składać się z kilku katalogów.

Pierwszy przypadek dotyczy projektów opracowywanych przez kilka osób, korzystających z różnych komputerów. Kierownik zespołu roboczego może np. utworzyć nowy projekt tylko dla celów administracyjnych - pliki źródłowe będą rezydowały na komputerach poszczególnych programistów, którzy w miarę postępów prac będą umieszczali kolejne wersje w archiwum. W takiej sytuacji jest prawdopodobne, iż kierownik zrezygnuje z przechowywania poszczególnych projektów na swoim komputerze, a tym samym nie będzie definiował położenia katalogu lokalnego.

Nazwa „katalog lokalny” może odnosić się również do całej grupy katalogów. TeamSource umożliwia obsługę takich sytuacji, o ile wszystkie katalogi w grupie mają wspólny katalog główny, tj. należą do tej samej gałęzi drzewa katalogów. Jeśli np. w skład projektu utworzonego w C++Builderze wchodzi zawartość katalogów D:\programy\projekty\mailprog\form1.cpp i D:\programy\biblioteki\internet\email.cpp, katalogiem lokalnym należy uczynić D:\programy\. Ponieważ najprawdopodobniej zawiera on także inne podkatalogi, nie będące częścią naszego projektu, należy usunąć je z drzewa wchodzącego w skład projektu TeamSource; podobnie należałoby uczynić z elementami podkatalogu D:\programy\biblioteki\internet\ niezwiązanymi z projektem mailprog. Operację tę należy wykonać w dwóch etapach - najpierw włączając do projektu wszystkie pliki, a następnie usuwając niepotrzebne.

Alternatywnym rozwiązaniem mogłoby być utworzenie dwóch archiwów, zawierających odpowiednio pliki projektu mailprog oraz biblioteki zawartej w katalogu internet. Rozwiązanie takie upraszcza tworzenie samych projektów TeamSource, jednak utrudnia zarządzanie nimi. Załóżmy np., że programista odpowiedzialny za projekt mailprog dokonał jego modyfikacji i umieścił nową wersję w archiwum (czynność ta jest dość oczywista i trudna do przeoczenia). Jeśli jednak w trakcie modyfikacji zlokalizowano i poprawiono niewielki błąd w pliku email.cpp, istnieje szansa, że aktualizacja drugiego archiwum ujdzie uwadze programisty.

Ostrzeżenie
TeamSource umożliwia korzystanie z kilku równoległych katalogów lokalnych, przechowując w każdym z nich pełną kopię archiwum projektu. Jeśli projekt aplikacji (utworzony w C++Builderze) jest rozproszony w kilku katalogach, nie należy dodawać ich wszystkich do listy katalogów lokalnych.

Widoki projektu w programie TeamSource

Zawartość archiwum może być prezentowana na jeden z trzech sposobów, zwanych w terminologii TeamSource widokami (ang. view). Odpowiadające im okna noszą nazwy: Remote View (widok archiwum), Local View (widok lokalny) oraz History View (widok historii). Jak można się domyślać z nazw, widok archiwum przedstawia pliki zawarte w centralnym archiwum projektu; widok lokalny obrazuje różnice pomiędzy zawartością archiwum a lokalną kopią projektu (pozwala to określić zmiany, których należy dokonać w celu „zsynchronizowania” obu wersji); wreszcie widok historii prezentuje zapis zmian dokonanych w zawartości archiwum.

Widok archiwum

W celu wyświetlenia widoku archiwum można nacisnąć klawisz F7, kliknąć ikonę widoku archiwum (Remote View) w lewej części okna programu lub wydać polecenie Remote Project z menu View. Widok archiwum wykorzystuje sposób prezentacji znany z Eksploratora Windows - obszar roboczy okna podzielony jest na dwa panele, z których lewy zawiera drzewo folderów, zaś prawy - listę plików opisanych numerami wersji i datami.

Zmiana właściwości folderu

Kliknięcie prawym przyciskiem myszy wybranego elementu drzewa folderów wyświetla menu kontekstowe, umożliwiające przeglądanie ustawień wybranego folderu, a w przypadku posiadania uprawnień administratora - również usuwanie, dodawanie i zmianę parametrów folderów. Okno właściwości folderu, wyświetlane po wybraniu polecenia Properties, zawiera informacje identyfikujące używany system kontroli wersji, listy rozszerzeń plików włączonych i wyłączonych z projektu oraz tzw. reguły przetwarzania (ang. production rules). Te ostatnie informują system kontroli wersji o zależnościach pomiędzy plikami źródłowymi i wynikowymi o tych samych nazwach (np. reguła postaci .cpp -> .obj oznacza, że w wyniku skompilowania pliku o rozszerzeniu .cpp powstaje plik pośredni o tej samej nazwie i rozszerzeniu .obj). Dzięki temu TeamSource „wie”, że przechowywanie wersji określonych plików (w tym przypadku plików pośrednich) nie jest konieczne, o ile tylko zachowa się odpowiednie pliki źródłowe. Niestety, reguły przetwarzania należy definiować oddzielnie dla każdego folderu (TeamSource nie umożliwia zdefiniowania globalnego zestawu reguł dla całego projektu).

Operacje na plikach

Kliknięcie prawym przyciskiem myszy nazwy pliku wyświetlanej w prawym panelu okna wyświetla menu kontekstowe, umożliwiające wykonanie kilku operacji. Najczęściej wykorzystywane jest tu polecenie Compare Revisions (porównanie wersji). Dostępne w menu polecenia przedstawiono poniżej.

Widok lokalny

Wyświetlenie widoku lokalnego następuje po naciśnięciu klawisza F8, kliknięciu ikony widoku lokalnego (Local View) lub wybraniu polecenia Local Project z menu View. Okno programu podzielone jest na dwa panele, zawierające sugerowany przez program wykaz plików przeznaczonych do zmodyfikowania (po lewej stronie wyświetlana jest zawartość systemu lokalnego, po prawej - archiwum).

Omawiany widok prezentuje archiwum z „lokalnego punktu widzenia” i jest prawdopodobnie najczęściej używaną przez programistów metodą przeglądania projektu. Umożliwia on umieszczenie w archiwum lokalnie zmodyfikowanych elementów projektu, znajdujących się w lewym panelu, a także aktualizację kopii lokalnej poprzez skopiowanie z prawego panelu elementów zmodyfikowanych przez innych programistów. W polu Action opisu każdego pliku znajduje się opis czynności, którą TeamSource sugeruje dla zachowania aktualności archiwum. Jeśli np. zawartość lokalnej kopii danego pliku uległa zmianie, w kolumnie Action prawego panelu pojawi się tekst Check in, zalecający umieszczenie nowej wersji pliku w archiwum.

Wykorzystanie widoku lokalnego do zapisywania plików w archiwum

Najczęściej stosowaną w praktyce funkcją programu TeamSource jest umieszczanie plików w archiwum. W odróżnieniu od innych programów realizujących zarządzanie wersjami, TeamSource nie wymaga każdorazowego blokowania plików i pobierania ich z archiwum - programista może dokonać zmian na własnej, lokalnej kopii i przekazać ją do archiwum później. Przebieg typowej operacji zapisu plików wygląda następująco: po wyświetleniu widoku lokalnego i ustaleniu, które pliki mają być umieszczone w archiwum (pliki takie oznaczone są w prawym panelu tekstem Check in) należy ustanowić blokadę, zaznaczyć odpowiednie pliki i kliknąć przycisk Do it! (wykonaj). Jeśli umieszczenie pliku wymaga uzupełnienia komentarza, odpowiedniego wpisu w pliku można dokonać przed wprowadzeniem zmian w oknie Check In Comment, wyświetlanym kliknięciem przycisku Comment.

Operacje na plikach w widoku lokalnym

W kolumnach Action obu paneli widoku lokalnego wyświetlane są opisy i ikony operacji, których wykonanie jest zalecane dla zachowania aktualności archiwum (lub kopii lokalnej). Zalecenia dla lokalnych kopii plików prezentowane są w prawym panelu, zaś dla kopii znajdujących się w archiwum - w lewym panelu okna. Pliki nie wymagające żadnej akcji nie są wyświetlane.

Zalecenia oparte są na podstawie porównania znaczników czasu oraz numerów wersji plików lokalnych, ich zarchiwizowanych odpowiedników oraz wersji bazowych. Jak powiedziano wcześniej, wersje lokalne znajdują się w systemie plików komputera lokalnego (używanego przez daną osobę), zaś wersje zarchiwizowane rezydują w archiwum zarządzanym przez system TeamSource. Nazwa „wersje bazowe” oznacza wersje plików aktualne w chwili ostatniej synchronizacji (umieszczenia w archiwum lub pobrania z archiwum). Podczas każdorazowego umieszczenia pliku w archiwum system zapisuje jego nazwę, numer wersji oraz datę i czas do specjalnego pliku o nazwie NazwaProjektu.tsl („NazwaProjektu” to nazwa odpowiedniego projektu TeamSource), umieszczonego w głównym katalogu projektu.

Proponowana przez system operacja zależy od różnic pomiędzy obiema wersjami. Poszczególne możliwości opisano krótko poniżej.

W przypadku pojawienia się zalecenia Correct by hand najlepiej jest wyświetlić informacje o podejrzanym pliku, klikając go prawym przyciskiem myszy i wybierając z menu polecenie View File Info. Pozwoli to zweryfikować znaczniki daty i czasu wersji lokalnej, zarchiwizowanej i bazowej, co może ułatwić usunięcie problemu. Źródłem zaleceń Correct by hand są na ogół czynniki zewnętrzne, jak np. przypadkowe skopiowanie poprzedniej wersji pliku do katalogu lokalnego. Inną pospolitą przyczyną tego rodzaju błędów mogą być niezgodności w obsłudze czasu przez poszczególne komputery wchodzące w skład sieci lokalnej. Sytuacja taka znana jest autorowi z praktyki - wykorzystywana przez niego kopia lokalna zawierała kilka plików oznaczonych komunikatem Correct by hand, natomiast na innym komputerze ten sam projekt zawierał ich znacznie więcej. Winne okazało się ustawienie strefy czasowej - zegar komputera autora ustawiony był na czas Wschodniego Wybrzeża (EST), zaś pozostałe stacje robocze wykorzystywały prawidłowe ustawienie GMT.

Pozostałe operacje wykonywane w widoku lokalnym

Dostępne w widoku lokalnym menu kontekstowe zawiera kilka innych poleceń operujących na plikach. Niektóre z nich dostępne są również poprzez klawisze skrótu. Polecenia menu kontekstowego opisano krótko poniżej.

View Local Changes. Polecenie to wyświetla różnice pomiędzy lokalną kopią pliku a wersją bazową, tj. najnowszą wersją pobraną z archiwum.

View All Changes. Polecenie to wyświetla różnice pomiędzy kopią lokalną a najnowszą wersją znajdującą się w archiwum (wersją zarchiwizowaną).

View Remote Changes. Polecenie to wyświetla różnice pomiędzy wersją zarchiwizowaną i bazową.

View File Info. Polecenie to umożliwia porównanie znaczników daty i czasu oraz numerów wersji lokalnej, zarchiwizowanej i bazowej.

Revert. Polecenie to zastępuje lokalną kopię pliku wersją pobraną z archiwum.

Change the Comments for the Selected File. Polecenie to umożliwia przejrzenie i zmodyfikowanie komentarzy związanych z danym plikiem.

Change the Recommended Action for the File. Polecenie to pozwala wybrać dla danego pliku akcję inną niż zalecana; najczęściej służy ono do zmiany operacji ręcznego scalenia plików (Merge by hand) na kopiowanie (Copy) lub umieszczenie w archiwum (Check in).

Move Files from One Pane to the Other. Polecenie to przenosi plik do drugiego panelu; wykorzystuje się je w razie konieczności wykonania operacji niedozwolonej w kontekście danego panelu.

Widok historii

Podobnie jak poprzednio, również w widoku historii obszar roboczy okna programu podzielony jest na dwa panele. W lewym panelu wyświetlany jest wykaz zapisów plików do archiwum (każda pozycja opatrzona jest datą i godziną zapisu oraz nazwą użytkownika, który go dokonał). Prawy panel zawiera szczegółowe informacje na temat wybranego zapisu (treść komentarza oraz listę umieszczonych w archiwum plików).

Mechanizmy kontroli wersji

System TeamSource wykorzystuje standardowo opracowaną przez firmę Borland bibliotekę kontroli wersji ZLib. Umożliwia on także bezpośrednie użycie mechanizmu PVCS firmy Merant, chociaż teoretycznie jest w stanie korzystać z dowolnego mechanizmu kontroli wersji.

Do wyboru biblioteki implementującej konkretny mechanizm kontroli wersji wykorzystuje się polecenie Controllers z menu Project. Sam plik biblioteki, noszący rozszerzenie .tsx (TeamSource Extension), jest zwykłą biblioteką dynamiczną, zawierającą definicje odpowiednich funkcji oraz interfejsów umożliwiających komunikację pomiędzy aplikacją TeamSource a właściwym mechanizmem kontroli wersji.

Zakładki

Obsługa historii wersji w systemie TeamSource umożliwia definiowanie tzw. zakładek (ang. bookmark). Utworzenie zakładki powoduje zapamiętanie bieżącego stanu wszystkich składników projektu, „utrwalając” jego stan i umożliwiając łatwy powrót do niego w przyszłości. Użyteczność zakładek przejawia się zwłaszcza w przypadku powiązania ich z opublikowanymi wersjami oprogramowania. Łatwo wyobrazić sobie sytuację, w której klient korzystający ze starszej wersji programu (opublikowanej np. rok temu) natrafia na problem i zgłasza go działowi pomocy technicznej. Odwołanie się do zakładki (o ile ją stworzono) pozwala szybko odtworzyć pliki źródłowe wersji używanej przez klienta, co bez wątpienia przyspiesza proces lokalizacji i usunięcia błędu.

W celu zdefiniowania zakładki należy wydać polecenie Bookmarks z menu Project. Powoduje to wyświetlenie okna dialogowego, umożliwiającego tworzenie (Add), modyfikowanie (Edit) i usuwanie (Delete) zakładek. Utworzenie nowej zakładki sprowadza się do nadania jej nazwy i określenia zasięgu za pomocą pól wyboru w grupie Scope. Zasięg lokalny (Local) oznacza, że zakładka będzie dostępna tylko dla użytkownika, który ją utworzył; użycie zasięgu globalnego (Global) udostępnia ją wszystkim użytkownikom projektu, wymaga jednak uprawnień administratora.

Odtwarzanie projektów z archiwum

W normalnym cyklu produkcyjnym zawartość katalogu lokalnego jest zwykle bardziej aktualna niż zawartość archiwum, bowiem bieżące zmiany dotyczą zawartości plików lokalnych, a dopiero później przenoszone są do archiwum. W niektórych przypadkach, np. gdy nad danym projektem pracuje kilka osób lub w razie awarii (utrata plików zapisanych na komputerze lokalnym), może się jednak okazać, że pliki przechowywane w archiwum są nowsze od kopii lokalnych. W takiej sytuacji może zajść potrzeba odtworzenia całego projektu z archiwum (ang. pulling), czyli zwykłego skopiowania plików na komputer lokalny.

Do odtworzenia projektu służy polecenie Pull To... z menu Project. Dostępna w oknie dialogowym Pull opcja Fast Pull pozwala na pominięcie odtwarzania plików, których bardziej aktualne odpowiedniki znajdują się już na komputerze docelowym. Jej wyłączenie powoduje bezwarunkowe skopiowanie wszystkich plików z archiwum. Możliwe jest również odtworzenie wersji plików określonych zakładką. W takiej sytuacji można się spodziewać, że niektóre (lub wszystkie) odtwarzane pliki będą starsze niż wersje obecne na komputerze lokalnym, toteż przed wykonaniem operacji warto zachować kopie bieżących plików, umieszczając je w archiwum.

Blokady

Zmiana zawartości archiwum przez któregoś z użytkowników projektu wymaga ustanowienia tzw. blokady (ang. lock). Najczęstszym powodem blokowania archiwum jest aktualizacja zawartych w nim plików; blokady wykorzystywane są również podczas definiowania i zmiany ustawień projektu przez administratora.

W odróżnieniu od kilku innych systemów kontroli wersji, TeamSource nie umożliwia blokowania wybranych plików, a jedynie całego archiwum. Ponadto zablokowanie archiwum konieczne jest tylko na czas umieszczania w nim nowej wersji, nie zaś, jak w przypadku wielu innych systemów, na cały czas przetwarzania danego pliku (od momentu pobrania go z archiwum aż do umieszczenia tam nowej wersji).

Ustanowienie blokady

W celu zablokowania archiwum należy wydać polecenie Request Lock z menu Project lub nacisnąć klawisz F4, a następnie podać orientacyjny czas trwania blokady (domyślnie wynosi on 5 minut). Upłynięcie zadanego czasu nie oznacza usunięcia blokady, ale pozwala innym użytkownikom zgłaszać żądania jej zniesienia. Posiadając uprawnienia administratora, można także ustanowić tzw. blokadę administracyjną (ang. administrator lock), nie pozwalającą na zgłaszanie żądań usunięcia i możliwą do utrzymania nawet po zakończeniu pracy systemu. Ustanawianą blokadę można wreszcie opatrzyć komentarzem, wyjaśniającym jej przeznaczenie.

Żądanie zniesienia blokady

Lista blokad dla bieżącego projektu wyświetlana jest w dolnej części okna programu. Jej zawartość stanowią blokady aktywne, oczekujące oraz zatwierdzane. Kliknięcie wybranej blokady prawym przyciskiem myszy wyświetla menu kontekstowe, umożliwiające zwolnienie, przedłużenie lub zmianę komentarza blokady, a także przekazanie jej oczekującemu użytkownikowi (Yield to) oraz żądanie zniesienia blokady (polecenie Verify Current Lock).

Zgłoszenie żądania zniesienia blokady (ang. challenging a lock) przed upływem przydzielonego jej czasu powoduje jedynie wyświetlenie ilości pozostałego czasu. Po upływie terminu ważności operacja ta powoduje wyświetlenie okna proszącego właściciela blokady o jej przedłużenie lub zwolnienie. Nieudzielenie odpowiedzi w czasie do dwóch minut powoduje automatyczne zniesienie blokady.

Program InstallShield Express

W ostatniej części rozdziału zajmiemy się dostarczanym w pakiecie C++Builder 5 programem InstallShield Express, służącym do tworzenia programów instalacyjnych. Ilość miejsca nie pozwoli nam co prawda omówić wszystkich jego aspektów, jednak przedstawione tu informacje powinny dać Czytelnikom solidne podstawy do dalszej pracy. Podstawowe metody tworzenia programu instalacyjnego są w większości przypadków takie same, jednak w razie potrzeby można skorzystać z dodatkowych funkcji oferowanych przez program InstallShield, rozszerzając możliwości tworzonego instalatora.

Instalacja programu InstallShield

InstallShield znany jest - przynajmniej z widzenia - wszystkim użytkownikom C++Buildera, wchodzi on bowiem standardowo w skład wszystkich wersji pakietu C++Builder, począwszy od wersji 1.0. Aby zainstalować go na komputerze, wystarczy umieścić płytę CD pakietu C++Builder 5 w napędzie CD-ROM i poczekać na automatyczne uruchomienie programu instalacyjnego. Jeśli to nie nastąpi, konieczne będzie przejście do folderu ISxpress na płycie CD i ręczne uruchomienie odpowiedniego instalatora, czyli programu Setupex.exe.

Wersja programu InstallShield dostarczana w pakiecie C++Builder nie jest wersją pełną. Została ona specjalnie przygotowana do współpracy z C++Builderem, a jednocześnie pozbawiona niektórych funkcji dostępnych w wydaniu komercyjnym. Nie zmienia to faktu, iż posiada ona praktycznie wszystkie funkcje niezbędne do tworzenia programów instalacyjnych dla dowolnych aplikacji.

Pierwsze kroki

Przed uruchomieniem programu InstallShield Express i rozpoczęciem budowy programu instalacyjnego warto zastanowić się przez chwilę nad niektórymi aspektami procedury instalacyjnej. Jeżeli np. podczas tworzenia aplikacji wybrano opcję konsolidatora Use Dynamic RTL (nakazującą dynamiczne dołączanie standardowej biblioteki C++Buildera do kodu aplikacji), program instalacyjny będzie musiał zawierać kod odpowiedniej biblioteki DLL. Dołączenie dodatkowych pakietów będzie konieczne także w przypadku wybrania opcji Build with Runtime Packages. Przeoczenie któregoś z dodatkowych plików może uniemożliwić uruchomienie aplikacji na komputerze użytkownika. Określenie sposobu tworzenia kodu wynikowego bywa kłopotliwe - jawne włączenie wszystkich bibliotek do pliku wykonywalnego powoduje znaczny wzrost jego rozmiaru, zaś użycie oddzielnych plików dołączanych dynamicznie wiąże się z koniecznością ich dystrybucji (pominięcie któregoś składnika może uniemożliwić działanie programu - przyp. tłum.). Dlatego też po zakończeniu prac nad właściwą aplikacją należy dokładnie określić skład zestawu plików wymaganych do jej uruchomienia, uzupełniając go o inne pliki pomocnicze, jak np. dokumentację elektroniczną, przykładowe dane itp. Tak skonstruowany zestaw warto umieścić w oddzielnym katalogu, co pozwoli łatwo przygotować program do dystrybucji.

Bezpośrednio po uruchomieniu InstallShield wyświetla okno dialogowe, umożliwiające utworzenie nowego programu instalacyjnego lub załadowanie jednego z uprzednio stworzonych projektów. W naszym przypadku utworzymy nowy projekt, wybierając opcję Create a new Setup Project. Kolejne okno pozwala na ustalenie nazwy projektu i jego lokalizacji (nazwę katalogu zawierającego projekt należy wpisać w polu New subdirectory, co pozwoli oddzielić pliki projektu od innych danych).

Wpisanie odpowiednich danych i kliknięcie przycisku OK przenosi nas do głównego okna programu InstallShield. Opcje kontrolujące zawartość i wygląd tworzonego programu zorganizowane są w postaci listy czynności, „odhaczanych” w miarę wykonywania (stąd używana w programie nazwa Setup Checklist). Główne okno programu i wyświetlaną w nim listę czynności przedstawiono na rysunku 18.4.

Rysunek 18.4. Główne okno programu i wyświetlana w nim lista czynności

Ustalenie wyglądu instalatora

Tworzenie programu instalacyjnego rozpoczyna się od ustalenia postaci, w jakiej będzie się on prezentował użytkownikowi. Związane z tym opcje skupione są na liście pod nagłówkiem Set the Visual Design.

Kliknięcie przycisku z ikoną strzałki położonego obok pozycji Application Information wyświetla okno dialogowe zawierające trzy karty. Pierwsza z nich, App Info, pozwala ustalić opisową nazwę instalowanej aplikacji (będzie ona wyświetlana m.in. w oknie apletu Dodaj/Usuń programy). Wybranie pliku wykonywalnego aplikacji (poprzez kliknięcie przycisku przeglądania położonego obok pola Application Executable) powoduje automatyczne dodanie jego nazwy do grupy aplikacji Program Files w oknie grup (Groups and Files) oraz umieszczenie ikony programu na karcie General okna ustawień folderów ikon (Specify Folders and Icons). Odpowiednie ustawienia można też zdefiniować oddzielnie.

Numer wersji aplikacji ustalany jest na podstawie informacji o wersji zawartej w zasobach pliku (a ta z kolei definiowana jest w ustawieniach projektu C++Buildera). Numer ten pozwala zabezpieczyć się przed przypadkowym zastąpieniem pliku programu przez starszą wersję. Pole Company pozwala na wpisanie nazwy producenta programu. Nazwa ta nie jest tylko i wyłącznie ozdobnikiem - jest ona używana do tworzenia ścieżek, opcji menu Start i niektórych wpisów w rejestrze, a także, co łatwo zauważyć, domyślnej nazwy katalogu docelowego. Ten ostatni parametr nie musi nam odpowiadać, toteż można rozważyć możliwość jego zmiany. Nie zaleca się przy tym usuwania z nazwy członu <ProgramFilesDir>, którego obecność nakazuje zainstalowanie programu w katalogu aplikacji (Program Files) na komputerze użytkownika. Ponieważ katalog ten może znajdować się na dysku innym niż C:, podczas instalacji użytkownik ma możliwość zmiany domyślnej lokalizacji katalogu docelowego.

Zawartość karty Main Window określa wygląd ekranu programu instalacyjnego. Wyświetlany w lewym górnym rogu ekranu tytuł aplikacji (w postaci tekstu lub mapy bitowej) określa się w polu Main Title, zaś logo producenta - w polu Logo Bitmap. Co prawda InstallShield dopuszcza użycie w obu przypadkach wyłącznie map 16-kolorowych, jednak w praktyce można zignorować to ograniczenie, o ile tylko możemy założyć, że ustawienia ekranu wykorzystują paletę co najmniej 256 kolorów (co jest praktycznie stuprocentowo bezpieczne - przyp. tłum.).

Karta Features zawiera tylko jedno pole wyboru, umożliwiające włączenie lub wyłączenie funkcji automatycznej dezinstalacji programu. Jej omawianie wykracza poza ramy naszej dyskusji, toteż domyślnego ustawienia (włączone) najlepiej po prostu nie zmieniać.

Opcje specyficzne dla C++Buildera 5

Kolejna grupa opcji, zatytułowana Specify InstallShield Objects for Borland C++Builder 5, pozwala określić elementy specyficzne dla aplikacji tworzonych za pomocą C++Buildera w wersji 5. Karta General wyświetlanego okna dialogowego zawiera listę składników programowych, z której należy wybrać komponenty używane w danej aplikacji. W określeniu zawartości listy pomocne jest ustalenie spisu plików wymaganych do pracy aplikacji (o czym mówiliśmy na stronie --> 32[Author:ts] ).

Zaznaczenie opcji BDE lub SQL Links wymaga wybrania także pozycji BDE Control Panel File. W pierwszym przypadku najrozsądniejsze jest zresztą uzupełnienie tworzonego pliku o pełną instalację systemu BDE, w przeciwnym razie bowiem ryzykujemy konflikt, jeśli w systemie docelowym znajdują się już inne aplikacje bazodanowe. W takiej sytuacji po zaznaczeniu na liście opcji BDE należy kliknąć przycisk Settings, co uruchomi kreator instalacji BDE, umożliwiający utworzenie odpowiednich aliasów na potrzeby instalowanej aplikacji. Procedura tworzenia aliasów jest następująca:

  1. Kliknij przycisk --> New [Author:ts] i wpisz nazwę aliasu (dokładnie w tej postaci, w jakiej zdefiniowano ją na komputerze źródłowym).

  1. Zdefiniuj parametry konfiguracyjne wprowadzonych aliasów (ścieżki, typy, dodatkowe parametry). Ze względów praktycznych pliki baz danych najlepiej umieszczać w podkatalogach katalogu macierzystego aplikacji, co wymaga uzupełnienia podawanej tu ścieżki przedrostkiem <INSTALLDIR>. Na przykład jeśli pliki bazy przechowywane są w podkatalogu bazy katalogu macierzystego aplikacji, należałoby użyć zapisu <INSTALLDIR>\bazy.

  2. Kliknij przycisk Zakończ. Kreator wygeneruje polecenia, zmieniające odpowiednie wpisy w rejestrze na komputerze docelowym i dołączy właściwe pliki do instalatora.

Pozostałe opcje dostępne na karcie General pozwalają dołączyć do pliku instalatora pakiety wykorzystywane przez aplikację (wykorzystuje ona dynamiczne łączenie pakietów). Szczegółowe informacje o dołączonych plikach znajdują się na karcie Advanced.

Wybór instalowanych składników i plików

Pliki wchodzące w skład instalatora podzielone są na „grupy tematyczne”, identyfikowane w projekcie wewnętrznymi nazwami. Z oczywistych względów nazwy takie powinny być czytelne i adekwatne do funkcji opisywanych elementów - innymi słowy użycie nazwy B1 jest jak najbardziej możliwe, jednak jej zrozumiałość za dwa miesiące może okazać się problematyczna. Warto podkreślić, że nazwy grup nie są widoczne dla użytkownika.

Pliki zawarte w danej grupie są zawsze instalowane w określonym katalogu. Sposób aktualizacji plików (istotny w przypadku obecności poprzednich wersji w systemie docelowym) można ustalić za pomocą opcji grupy File update method, dostępnych w oknie właściwości grupy (przycisk Properties), jednak najczęściej wykorzystuje się ustawienie domyślne (aktualizacja tylko starszych wersji). Najważniejszą grupę stanowią pliki tworzące aplikację; pozostałe grupy mogą obejmować dodatkowe składniki wybrane w poprzednim etapie. Utworzenia oddzielnej grupy wymagają także pliki baz danych (o ile mają zastosowanie w aplikacji), przy czym katalog docelowy dla grupy powinien być identyczny z określonym w ustawieniach aliasów BDE (zobacz poprzedni podpunkt).

Pliki „systemowe”, tj. biblioteki DLL, komponenty ActiveX itp., umieszcza się zwykle w katalogu Windows\System, symbolizowanym przez ciąg <WINSYSDIR>. Przy okazji warto jeszcze raz zweryfikować kompletność zestawu dołączanych do projektu plików bibliotecznych.

Do umieszczania plików w odpowiednich grupach najprościej jest wykorzystać technikę „przeciągnij i upuść”, przeciągając odpowiednie ikony wprost z okna Eksploratora Windows. Szybkie uruchomienie tego ostatniego umożliwia przycisk Launch Explorer, dostępny na karcie Groups i będący miniaturową kopią systemowej ikony Eksploratora (zobacz rysunek 18.5). Potem wystarczy już tylko odpowiednio ułożyć okna na ekranie, wybrać właściwy folder i przeciągnąć pliki do właściwej grupy.

Rysunek 18.5. Karta Groups okna instalowanych składników - dwa spośród instalowanych plików znajdą się grupie aplikacji, trzeci w grupie Dane

Aby utworzyć nową grupę, należy kliknąć przycisk New Group, wpisać nazwę tworzonej grupy i wybrać katalog docelowy lub zaakceptować lokalizację domyślną.

Opcje dostępne na karcie Components pozwalają na definiowanie grup składników umożliwiających instalację wariantową. Zagadnienie to jest dość złożone i nie będziemy się nim tutaj zajmować.

Elementy interfejsu użytkownika

Wybranie z listy czynności pozycji Dialog Boxes wyświetla okno dialogowe, pozwalające określić wygląd i zachowanie instalatora w trakcie pracy. Jest to zapewne najbardziej atrakcyjny etap projektowania instalatora, a bogactwo możliwości pozwala projektantom rozwinąć swoją inwencję. Nawet nie wdając się w definiowanie własnych okien dialogowych i obrazków, warto zadbać, by wyświetlane informacje odpowiadały instalowanej aplikacji - domyślne wartości proponowane przez program InstallShield mogą okazać się zbyt ogólnikowe lub w ogóle nieodpowiednie.

Przywitanie użytkownika atrakcyjną winietką (ang. welcome bitmap) bez wątpienia dodaje aplikacji blasku, jednak odbywa się kosztem powiększenia objętości pliku, co w przypadku dystrybucji poprzez Internet jest czynnikiem bardzo istotnym. Oczywiście jeśli zamierzamy rozprowadzać aplikację na płytach CD-ROM, wielkość plików staje się zagadnieniem marginalnym i można bez problemu pozwolić sobie na artystyczne szaleństwa.

Opcje Software License Agreement i Readme umożliwiają wyświetlenie okien zawierających treść licencji oraz pliku z najważniejszymi informacjami (Readme lub Czytaj). Dystrybutorzy oprogramowania klasy shareware i freeware zalecają przy tym, by treść umowy licencyjnej wyświetlać nie tylko w programie instalacyjnym, ale także udostępniać w postaci oddzielnego dokumentu (np. pliku --> tekstowego[Author:ts] ). Co prawda użytkownicy rzadko zadają sobie trud czytania umów licencyjnych i plików Readme, jednak nie należy im tego dodatkowo utrudniać. Warto także pamiętać, że długość wierszy tekstu wyświetlanego w obu wspomnianych oknach nie powinna przekraczać 65 znaków, w przeciwnym przypadku sposób jego wyświetlenia może nie odpowiadać pierwotnej postaci. Może to wymagać przeformatowania tekstu, np. za pomocą Notatnika (przy wyłączonej opcji zawijania wierszy).

Kolejne dwie opcje, Choose Destination Location i Choose Database Location, pozwalają ustalić położenie katalogów, zawierających pliki samej aplikacji, oraz wykorzystywanej przez nią bazy danych. Opcje Setup Type i Custom Setup umożliwiają wyświetlenie okien dialogowych, sterujących instalacją wariantową; stosuje się je tylko w przypadku wcześniejszego zdefiniowania grup składników w oknie Specify Components and Files. Okno dialogowe Select Program Folder pozwala użytkownikowi określić docelowe położenie ikon aplikacji. Wreszcie opcje Start Copying Files i Progress Indicator pozwalają wyświetlić okno podsumowania (pozwalające na sprawdzenie wybranych ustawień) oraz okno postępu, informujące o przebiegu procesu instalacji. Wygląd każdego okna można podejrzeć, klikając przycisk Preview (wyświetlany na ekranie przykład nie uwzględnia co prawda zmian wprowadzonych w projekcie, ale pozwala zorientować się w ogólnym układzie okna).

Atrakcyjnym sposobem przekazywania użytkownikom informacji o instalowanym programie i innych produktach firmy są plansze reklamowe (ang. billboard), czyli obrazki przechowywane w sekwencyjnie ponumerowanych plikach BMP (nazwa pliku składa się ze stałego przedrostka, np. Setup, oraz numeru kolejnego, czyli np. setup1.bmp, setup2.bmp itd. - przyp. tłum.). Kolejne plansze wyświetlane są automatycznie w trakcie instalacji. Decydując się na wykorzystanie tego mechanizmu, warto wziąć pod uwagę dwa czynniki:

Ostatnie okno, Setup Complete, ma zastosowanie tylko w przypadku instalowania plików, których poprawne zainstalowanie lub aktywacja wymagają ponownego uruchomienia komputera (np. biblioteki dynamiczne, komponenty ActiveX).

Modyfikacja wpisów w rejestrze

Dwie pozycje skupione w grupie Make Registry Changes umożliwiają tworzenie lub modyfikowanie wpisów w rejestrze, wymaganych do poprawnej pracy aplikacji. Mogą to być np. ustawienia domyślne (wymagane podczas pierwszego uruchomienia), informacje o położeniu plików itd.

W celu zmiany określonego wpisu należy przede wszystkim zlokalizować klucz rejestru, przechowujący odpowiedni parametr aplikacji (nazwa klucza i wartość parametru wynikają z konstrukcji programu). W tym celu wystarczy wybrać odpowiednią pozycję drzewa wyświetlanego na karcie Registry - Keys, a następnie kliknąć przycisk Add Key i wpisać pełną nazwę klucza w polu New Key. W naszym przypadku nazwą tą jest CBUILDER\TEST\INSTALL, zaś cały klucz to oczywiście HKEY_CURRENT_USER\CBUILDER\TEST\INSTALL, co pokazano na rysunku 18.6.

Rysunek 18.6. Definiowanie nazwy klucza rejestru w oknie Make Registry Changes

Ewentualne pomyłki można skorygować, klikając przycisk Modify Key lub usuwając błędnie utworzony klucz. Zaznaczenie pola wyboru Uninstall Key nakazuje automatyczne usunięcie klucza podczas dezinstalacji programu.

Właściwą wartość wpisu ustala się na karcie Registry - Values po uprzednim wybraniu odpowiadającego jej klucza. Kliknięcie przycisku Add Value wyświetla okno umożliwiające zdefiniowanie nazwy i wartości wpisu oraz typu tej ostatniej (String - tekst; Binary - blok bajtów; DWORD - podwójne słowo, podawane w zapisie szesnastkowym lub --> dziesiętnym[Author:ts] ). W większości przypadków definiowane wartości są typu tekstowego, chociaż aplikacja może narzucać w tej kwestii inne wymagania.

Ustawienia menu Start

Okno dialogowe Specify Folders and Icons pozwala na ustalenie parametrów uruchomienia i wybranie ikon oraz folderów wykorzystywanych przez program. Wartości domyślne dla głównego pliku wykonywalnego aplikacji ustalane są na podstawie informacji wprowadzonych w pierwszym etapie projektowania (okno Set the Visual Design). Ikony pozostałych składników aplikacji (wyświetlane w menu Start) muszą zostać dodane ręcznie. W tym celu należy kliknąć przycisk przeglądania (...) znajdujący się obok pola Run Command (zobacz rysunek 18.7), wybrać z wyświetlonego drzewa odpowiedni plik, wprowadzić ewentualne parametry jego wywołania (Run parameters) oraz tekst opisu wyświetlanego w menu Start (Description) i na koniec kliknąć przycisk Add Icon. Czynności te powtarza się dla każdego elementu aplikacji, który ma być reprezentowany w menu Start. Warto pamiętać, że dla większości plików (np. dokumentów tekstowych, plików pomocy) standardowe ikony zapewnia system operacyjny.

Rysunek 18.7. Definiowanie ikon składników aplikacji

Karta Advanced pozwala na zdefiniowanie dodatkowych ustawień wybranego składnika aplikacji. Opcje grupy Folder określają położenie skrótu; najczęściej wybierana jest opcja Programs Menu, nakazująca umieszczenie skrótu w menu Start|Programy. Alternatywą jest użycie opcji Start Menu (umieszczenie ikony bezpośrednio w menu Start) lub Desktop (na pulpicie). Tej ostatniej możliwości warto używać z umiarem, chociaż umieszczenie ikony skrótu na pulpicie Windows ułatwia życie początkującym użytkownikom. Pozostałe dwie opcje, Startup i Send To, pozwalają umieścić skrót w menu Autostart (co powoduje automatyczne uruchomienie aplikacji w chwili rozpoczęcia pracy systemu) lub w folderze Wyślij do.

Pole Start in umożliwia określenie katalogu roboczego aplikacji. Do zatwierdzenia wprowadzonych ustawień służy przycisk Modify Info.

Utworzenie pliku instalatora

Wybranie z listy pozycji Disk Builder wyświetla okno, umożliwiające skompilowanie całego projektu do postaci pliku instalacyjnego (lub kilku plików). Pole Disk Size umożliwia wybranie rodzaju nośnika, który posłuży do dystrybucji plików. Przykładowo, wybranie opcji 1.44 MB powoduje wygenerowanie tzw. obrazów dyskietek instalacyjnych (zestawów plików mieszczących się na pojedynczych dyskietkach) i zapisanie ich w oddzielnych folderach. Możliwe jest też spakowanie wszystkich elementów do pojedynczego pliku przeznaczonego do dystrybucji na płytach CD-ROM.

Po wybraniu rodzaju nośnika pozostaje już tylko kliknąć przycisk Build. Raport z przebiegu kompilacji wyświetlany jest w polu Feedback; w przypadku wystąpienia błędów wystarczy skorygować odpowiedni element projektu i ponowić kompilację.

Ukończony projekt najlepiej zapisać na dysku, co pozwoli wrócić do niego w przyszłości, dokonać zmian (np. uzupełnić o nowe pliki) i skompilować ponownie, przygotowując w ten sposób kolejną wersję instalacyjną aplikacji.

Przeniesienie plików na nośnik

Ostatnie okno dialogowe programu InstallShield, wywoływane poleceniem Copy to Floppy, pozwala skopiować utworzone obrazy dysków instalacyjnych na fizyczny nośnik, czyli dyskietki. W tym celu należy wybrać docelowy napęd (lub ścieżkę sieciową) w polach grupy Destination, a następnie kliknąć przycisk Copy All Disk Images. Warto zauważyć, że kopiowanie można też wykonać „ręcznie”, np. w Eksploratorze Windows, przeciągając zawartość odpowiedniego katalogu na ikonę dyskietki (obrazy dyskietek tworzone są już w poprzednim etapie). Przed kopiowaniem należy oczywiście zaopatrzyć się w odpowiednią liczbę dyskietek i zaetykietować je.

Wersja programu InstallShield Express dostarczana w pakiecie C++Builder 5 nie pozwala na tworzenie pojedynczych, samorozpakowujących się plików instalacyjnych. Funkcję tę zapewnia dostępne odpłatnie narzędzie InstallShield Package for the Web (zobacz http://www.installshield.com). Alternatywą jest użycie programu archiwizującego, jak np. PKZIP czy WinZip Self Extractor, umożliwiającego utworzenie tzw. pliku SFX, czyli samorozpakowującego się archiwum, umożliwiającego uruchomienie wybranego pliku po zakończeniu rozpakowywania (należy pamiętać, że pliki SFX utworzone za pomocą bezpłatnych wersji tych programów można rozpowszechniać wyłącznie na zasadzie niekomercyjnej). Metoda ta jest praktycznie jedynym wyjściem w przypadku dystrybucji internetowej, w której liczy się każdy bajt objętości pliku.

Testowanie programu instalacyjnego

Po utworzeniu programu instalacyjnego należy sprawdzić poprawność jego działania. Metoda używana przez autora polega na uruchamianiu programu na komputerze źródłowym (na którym został utworzony) i dokonywaniu ewentualnych zmian i poprawek aż do momentu uzyskania zadowalającego efektu. Wprowadzanie wszelkich modyfikacji i ponowna kompilacja programu nie nastręcza większych problemów, należy jedynie pamiętać o odinstalowaniu poprzedniej wersji przed kolejną instalacją.

Po osiągnięciu satysfakcjonujących wyników można już spróbować zainstalować program na innym komputerze. W idealnym przypadku konfiguracja testowego systemu powinna być możliwie „czysta”, tj. nie zawierać żadnych składników, mogących wpływać na działanie instalowanej aplikacji, co zapewniłoby obiektywność testu. W praktyce jest to mało prawdopodobne, chociaż w przygotowanie konfiguracji testowej warto włożyć nieco wysiłku.

Niepowodzenie instalacji testowej nie jest oczywiście niczym strasznym - w takiej sytuacji wystarczy powrócić do komputera źródłowego, zmienić ustawienia będące źródłem problemu, ponownie skompilować projekt i powtórzyć testowanie. Kilkakrotne powtórzenie takiego cyklu powinno zaowocować usunięciem wszystkich usterek. Po udanym zainstalowaniu aplikacji można przystąpić do bardziej wymagających testów, np. instalacji na innych dyskach i w innych folderach, instalowania tylko wybranych składników itd. Ten etap testowania może okazać się czasochłonny, jednak lepiej chyba włożyć nieco wysiłku w przygotowanie prawidłowo działającego programu, niż narażać się na pretensje ze strony użytkowników, którym nie udało się zainstalować aplikacji mozolnie „ściągniętej” z Internetu.

Praktyka czyni mistrza, a tworzenie programów instalacyjnych nie jest tu wyjątkiem. Dlatego też przed stworzeniem pierwszego „prawdziwego” pakietu instalacyjnego najlepiej zapoznać się wykorzystywanym narzędziem i nabrać nieco wprawy. Nabyte w ten sposób umiejętności z pewnością zaprocentują w warunkach rzeczywistych projektów i związanych z nimi ograniczeń czasowych.

Podsumowanie

Zagadnienia poruszone w niniejszym i poprzednim rozdziale stanowią podstawy niezbędne do opanowania zasad instalowania, dystrybucji, konserwacji i promocji oprogramowania. Mimo iż nasza dyskusja osadzona była silnie w kontekście C++Buildera, przedstawione tu techniki stosują się w równym stopniu do oprogramowania tworzonego za pomocą innych narzędzi. Ich właściwe stosowanie może w znaczący sposób poprawić wydajność pracy i jakość tworzonych produktów, a co za tym idzie - zadowolenie ich użytkowników.

W rozdziale tym omówiliśmy zasady instalowania i konserwacji oprogramowania oraz różne metody tworzenia plików instalacyjnych, począwszy od konstrukcji plików CAB i INF, a skończywszy na wyspecjalizowanych narzędziach - programach Install Maker firmy ClickTeam oraz InstallShield Express. Kilka stron poświęciliśmy także kontroli wersji i realizującemu ją programowi TeamSource, wchodzącemu w skład pakietu C++Builder 5 Enterprise.

--> Opcje te mogą nie działać prawidłowo w trybie testowania instalatora w programie Install Maker (wersja 1.2e). Nazwy wpisywane w oba pola edycyjne muszą określać pliki istniejące w systemie źródłowym, dlatego też najlepiej wybierać je za pomocą przycisków przeglądania - przyp. tłum.

Operacja taka jest w praktyce dość uciążliwa, zwłaszcza jeśli numery wersji zmieniają się szybko. Warto poświęcić nieco czasu na zaprogramowanie funkcji pobierającej numer wersji z zasobów aplikacji i wyświetlającej ją w etykiecie w sposób automatyczny - przyp. tłum.

Warto jednak pamiętać o drugiej stronie medalu: uaktualnienie rozprowadzane w postaci zestawu poprawek zajmuje zwykle o wiele mniej miejsca (zamiast płyty CD-ROM może np. wystarczyć dyskietka, niebagatelne znaczenie ma też skrócenie czasu transmisji pliku) - przyp. tłum.

1

pozwalam sobie połączyć kolejne podpunkty w całość - w oryginale drugi jest odwróceniem pierwszego (czyli jest nadmiarowy), a poza tym argumentacja podana przez autora jest nonsensowna - uszkodzenie jednego z kilku plików jest tak samo groźne, jak uszkodzenie jednego dużego pliku.

wg oryginału znajduje się on na płycie CD, ale nic takiego na niej nie ma (jest tylko PatchMaker). Na razie usuwam odpowiedni fragment z tłumaczenia (jeżeli wersja freeware zostanie zamieszczona w polskiej wersji, trzeba będzie o tym wspomnieć).

wbrew oryginałowi, w tym kroku nie ustala się katalogu docelowego.

w oryginale jest zrzut ekranu, którego cytowanie nie ma sensu - każdy może sobie go obejrzeć, a poza tym byłyby kłopoty z tłumaczeniem. Zastępuję zrzut tabelą opisującą polecenia i opcje programu (uwaga - tabela jest podzielona na dwie części). UWAGA: pozostałe tabele przenumerowuję o jeden w górę, pozostałe wydruki przenumerowuję o jeden w dół.

przenumerowuję tabele o jeden w górę

brak opisu sekcji w specyfikacji SDK/DDK

w oryginale Applications directory; podaję za dokumentacją Windows DDK.

przenumerowuję o 1 w dół, oryginalnego wydruku 29.1 już nie ma

Rozdział 22 jest na CD - zakładam, że zostanie przetłumaczony (jeśli nie, zdanie trzeba będzie usunąć).

Ze względu na brak rozdziału 22 przeredagowałem cały akapit.

nie mam pojęcia, co autor miał na myśli pisząc „tab” (pewnie interfejs użytkownika), ale technicznie sprowadza się to do dwóch tabel z danymi.

Nie ma komponentu TEmail; jest TSMTP, który robi mniej więcej to samo.

w oryginale niezrozumiały passus o ANSI code (być może chodziło o ASCII, ale nadal to jest nonsens)

w tym kroku nie ustala się katalogu docelowego!

w oryginale trochę masło maślane, nieco zmieniłem.

zamieniam drugi poziom wyliczenia na wypunktowanie - kolejność punktów nie ma w zasadzie znaczenia, a ortograficznie jest znacznie lepiej.

w oryginale nonsens, tu nie ma mowy o żadnym wyborze typu projektu.

uwaga, odsyłacz do zakładki

w oryginale Next

W oryginale ten akapit jest w następnym punkcie, ale logicznie i fizycznie należy do tego.

związek plików Zip z tym wszystkim jest dość słaby; nie mam pojęcia, o co mogło autorowi chodzić? jest dobrze tak jak napisano.

Z jakichś przyczyn pominięto to w oryginale, a pierwsze okno jest dość ważne

w oryginale jest „DWORD He”, hm...

tego nie ma w oryginale, dlaczego? te informacje są równie ważne, co opis lokalizacji skrótu.

[Author:ts]

Wyszukiwarka

Podobne podstrony:
R14-03, ## Documents ##, C++Builder 5
R17-03, ## Documents ##, C++Builder 5
R04-03, ## Documents ##, C++Builder 5
R13-03, ## Documents ##, C++Builder 5
R08-03, ## Documents ##, C++Builder 5
R09-03, ## Documents ##, C++Builder 5
R05-03, ## Documents ##, C++Builder 5
R07-03, ## Documents ##, C++Builder 5
R03-03, ## Documents ##, C++Builder 5
R15-03, ## Documents ##, C++Builder 5
R16-03, ## Documents ##, C++Builder 5
R02-03, ## Documents ##, C++Builder 5
R11-03, ## Documents ##, C++Builder 5
r18-07, ## Documents ##, Windows 2000 Server. Vad. prof
r-13-00, ## Documents ##, C++Builder 5
r-12-00, ## Documents ##, C++Builder 5
2011 03 03 Document 001
r18 03
r-10-00, ## Documents ##, C++Builder 5

więcej podobnych podstron