NSIS, czyli jak w prosty sposób stworzyć instalator pod Windowsa

Jeśli tworzenie aplikacji desktopowych nie jest Ci obce, to z pewnością wiesz, że w toku rozwoju tego typu oprogramowania wcześniej lub później przychodzi moment, w którym trzeba zastanowić się nad sposobem jego dystrybucji. Wiele zależy tu od użytych technologii oraz środowiska, na które kierujemy swoje programy. Na przykład jeśli korzystamy z Javy, to jedną z oczywistych możliwości będzie tworzenie i udostępnianie jarów, zaś pisząc apkę przeznaczoną dla systemu Ubuntu, zapewne dobrze będzie wygenerować .deba z naszym dziełem. A co w przypadku Windowsa? Większość programów, których używamy, jest przez nas instalowanych. Instalowanych – to własnie słowo klucz na dziś. A zatem potrzebujemy instalatora – pojedynczego pliku, który możemy udostępnić innym, ci zaś, przy pomocy kilku kliknięć, mogą wypakować nasze oprogramowanie w żądane miejsce.

Stajemy więc przed pytaniem: jak stworzyć taki instalator? Jakich narzędzi, bibliotek, technologii należałoby użyć? Okazuje się, że dostępnych rozwiązań jest całkiem sporo – niektóre z nich są płatne (np. popularny InstallShield), inne darmowe. Jedne wymagają przyswojenia pewnej dawki wiedzy zanim efektywnie będziemy mogli ich używać, inne z kolei charakteryzują się nieco większą prostotą (połączoną niekiedy z mniejszą liczbą funkcjonalności). Jeśli rozglądamy się za bezpłatnymi narzędziami, warto przyjrzeć się zwłaszcza dwóm poniższym:

  • WiX Toolset – rozbudowane oprogramowanie, pozwalające na generowanie plików MSI (Windows Installera). Swego czasu był stosowany nawet w Microsofcie, m.in. do stworzenia instalatora dla Microsoft Office 2007 [2]. Niestety w parze z mnogością funkcji idzie pewien poziom skomplikowania – tutaj możecie zobaczyć przykład realnego wykorzystania WiXa i przyjrzeć się jak wyglądają używane w takim przypadku pliki XML-owe.
  • NSIS (Nullsoft Scriptable Install System) – narzędzie umożliwiające tworzenie instalatorów (w postaci plików .exe) przy pomocy prostego języka skryptowego. Innym dziełem tego samego producenta jest np. Winamp, więc działanie wygenerowanego przez NSIS instalatora zapewne część z Was widziała w akcji przy instalacji tego właśnie programu.

W tym artykule zajmiemy się drugim z wymienionych tu rozwiązań. Do jego zalet należą:

  • lekkość – narzut (ang. overhead) wynosi zaledwie 34 KB, tzn. że o tyle zwiększy się rozmiar naszego programu jeśli użyjemy instalatora NSIS
  • prostota i łatwość użytkowania dzięki użyciu bazowaniu na skryptach
  • przenośny kompilator – instalator możemy przygotowywać nawet na systemach uniksowych (i wcale nie potrzebujemy do tego Wine)
  • wsparcie dla instalacji opierającej się o pobieranie plików z internetu

Pełną listę oferowanych funkcjonalności można znaleźć na oficjalnej stronie NSIS.

Przykładowy instalator

Zobaczmy zatem jak wygląda w NSIS jakieś instalatorowe „Hello World”. Na oficjalnej stronie (pod tym linkiem) można znaleźć kilka przykładów bardzo prostych instalatorów. Wśród nich znajduje się np. taki (usunąłem z niego komentarze):

Aby z powyższego skryptu wygenerować plik .exe musimy pobrać NSIS i uruchomić narzędzie MakeNSIS, klikając link „Compile NSIS scripts” w głównym oknie NSIS. Następnie ładujemy skrypt (zapisany uprzednio z rozszerzeniem .nsi) i kompilujemy go. Z racji, że w kodzie odwołujemy się do pliku test.txt, powinniśmy umieścić go z tym sasmym folderze, w którym zapisaliśmy skrypt.

Sam kod jest chyba dość oczywisty, ponieważ ogranicza się do zdefiniowania następujących rzeczy:

  • wygenerowany plik instalatora ma mieć nazwę „simple installer.exe”
  • katalogiem instalacyjnym będzie pulpit
  • kopiujemy plik test.txt do katalogu instalacyjnego

Po uruchomieniu instalatora, naszym oczom ukaże się takie oto okno:

Instalator NSIS
Prosty instalator stworzony przez NSIS

Jak widać instalacja natychmiastowo się zakończyła, a użytkownik nie został nawet o nic zapytany. Plik test.txt został przekopiowany na pulpit, a jedyna interakcja, na jaką pozwala instalator to zamknięcie okna. Wizualnie też nie wygląda to zbyt nowocześnie.

Na szczęście NSIS zawiera coś, co jest doskonałą odpowiedzią na potrzeby osób, które niewielkim wysiłkiem chcą stworzyć nieco ładniej wyglądający instalator, posiadający typowe dla tego rodzaju programów możliwości, tj.:

  • przesdtawienie licencji do zaakceptowania
  • wybór przez użytkownika folderu docelowego
  • wybór komponentów aplikacji, które mają zostać zainstalowane
  • możliwość dodania skrótu na pulpicie oraz w menu start
  • dodanie dezinstalatora

Nowoczesny interfejs

Odpowiedzią tą jest komponent o nazwie NSIS Modern User Interface, dzięki któremu szybko można wygenerować spełniający te kryteria instalator. Poniżej prezentuję skrypt stworzonego przeze mnie przykładowego instalator, w którym wykorzystałem właśnie Modern UI:

Częściowo bazowałem na jednym z przykładów z oficjalnej strony NSIS – z niego pochodzą znajdujące się w kodzie komentarze, których pozwoliłem sobie nie usuwać. Główna logika instalatora zdefiniowana została w miejscu, gdzie znajdują się dyrektywy wstawiające makra poszczególnych kroków:

Nazwy makr są dosyć opisowe, więc już na pierwszy rzut oka widać jak będą wyglądały kolejne kroki naszego instalatora:

  1. Strona z informacjami powitalnymi
  2. Licencja do zaakceptowania (jej treść wczytujemy z osobnego pliku tekstowego)
  3. Nasza customowa strona
  4. Wybór komponentów do instalacji
  5. Wskazanie przez użytkownika folderu docelowego
  6. Dodawanie wpisu do Menu Start
  7. Właściwa instalacja plików
  8. Strona z informacjami końcowymi

Kolejne wstawiane makra dotyczą natomiast dezinstalatora, który zostanie dołączony do naszego programu.

Poszczególne strony dostosowujemy w różny sposób, zależnie od ich typu. Przy licencji wskazujemy plik zawierający jej treść, zaś jeśli chodzi o informacje powitalne, po prostu definiujemy odpowiednią stałą:

Z kolei komponenty, mające znajdować się na liście elementów do wyboru określamy, korzystając z sekcji, np.:

Powyższa sekcja będzie wyświetlana jako „Additional Tools”, z napisem „Set of additional tools” pojawiającym się z prawej strony okna instalatora po najechaniu myszką, i domyślnie będzie niezaznaczona (opcja /o). Fragment ${LANG_ENGLISH} to element związany z funkcjonalnością NSIS, pozwalającą na wybór przez użytkownika języka instalacji (w naszym przykładzie akurat jej nie używamy). Sama sekcja jest pusta, co oznacza, że zaznaczenie tego komponentu nie spowoduje żadnych dodatkowych działań.

Sporo działań mamy natomiast w drugiej sekcji:

Wreszcie używamy katalogu instalacyjnego wybranego przez użytkownika ($INSTDIR), aby przekopiować tam (rekurencyjnie, bo z opcją /r) katalog myApp.  Oprócz tego dodajemy wpis w rejestrze systemowym, tworzymy dezinstalator oraz dodajemy skróty do Menu Start: najpierw tworzymy w nim katalog (jego nazwa jest zapisana w zmiennej $StartMenuFolder i może zostać zmodyfikowana przez użytkownika), a następnie dodajemy do niego skróty do dezinstalatora oraz pliku uruchomieniowego aplikacji.

Dodatkowe kroki

A co, jeśli chcemy od naszego instalatora coś więcej niż tylko parę generycznych kroków? Może np. potrzebujemy dodatkowych formularzy, aby uzyskać od użytkownika niezbędne informacje? W takiej sytuacji pewna doza kodowania staje się nieunikniona, ale bynajmniej nie ma tu nic skomplikowanego. W załączonym przykładzie stworzyłem dodatkowy krok, umożliwiający wybór jednej z trzech opcji (czyli tzw. radio buttons).

 

Aby obsłużyć taki przypadek wymagane jest napisanie dwóch funkcji, których nazwy przekazujemy do obiektu strony: Page Custom GetEnvPageCreate GetEnvPageLeave. Pierwsza z metod odpowiada za utworzenie wszystkich elementów graficznych, z kolei druga za obsługę opuszczenia kroku (kliknięcia Next).

Sama ifologia raczej nie wymaga omówienia (ot, po prostu używamy charakterystycznej dla tego języka składni instrukcji warunkowej), za to warto wyjaśnić jej przeznaczenie w funkcji GetEnvPageCreate, ponieważ może nie być to oczywiste na pierwszy rzut oka. Otóż sprawdzenia w liniach 15-23 odpowiadają za to, aby jeśli przejdziemy do kolejnego kroku instalacji, to po cofnięciu się nasz wcześniejszy wybór był zapamiętany. Dokonany przez użytkownika wybór zapisujemy sobie w zmiennej $EnvType, której później możemy użyć np. przy zapisie konfiguracji do pliku. Jeśli taki sposób tworzenia własnych kroków i tak brzmi dla Ciebie strasznie, to dobrą informacją będzie fakt, że istnieją programy wspomagające ich tworzenie. Jednym z nich jest HM NIS EDIT, w którym generowanie customowych formularzy sprowadza się do drag&drop.

Poniżej zamieszczam jeszcze parę screenshotów, pokazujących końcowy wygląd stworzonego instalatora. Jeśli taki wygląd nie wydaje Ci się satysfakcjonujący, to pozostaje skorzystać z… NSIS Ultra-Modern User Interface! 😀

 

Kompilacja pod Linuksem

Jedną ze znaczących dla mnie zalet NSIS jest możliwość kompilacji jego skryptów i generowania pliku instalatora na systemach uniksowych. Osobiście przetestowałem sposób, który dla NSIS w wersji 2.x opisany został na blogu Alejandro Celaya i śmiało mogę potwierdzić, że działa on również dla wydania 3.x, a stworzone w ten sposób pliki .exe poprawnie wykonują swoją pracę pod Windowsem. Ta funkcjonalność NSIS otwiera całe spektrum zastosowań w projektach, w których część usług i komponentów jest uruchamiana na Linuksie. Instalatory mogą być w prosty sposób generowane w środowiskach ciągłej integracji (np. na Jenkinsie) lub po stronie innego działającego na Linuksie serwera.

Podsumowanie

Na tyle na ile poznałem NSIS, mogę opisać je jako rozwiązanie lekkie i proste, a przy tym nie na tyle niszowe, aby znalezienie odpowiedzi na większość pojawiających się przy developmencie problemów stanowiło trudność. Na samym StackOverflow zadano już ponad 2 tysiące pytań na temat NSIS, a i sama dokumentacja jest całkiem dobra. Warto też wspomnieć o projekcie Pawła Porwisza, który wykonał dużą pracę dla polskojęzycznych użytkowników, przygotowując polską wersję dokumentacji, dostępną na jego stronie internetowej.

Linki i źródła

  1. NSIS – strona oficjalna.
  2. WiX: Hints for New Users (Part 1 of 3).
  3. NSIS Modern User Interface.
  4. NSIS Modern UI – przykłady.
  5. Polska dokumentacja NSIS, Paweł Porwisz.
.