Rozdział 5: Polecenia kompilacji

Ten dokument zgodny jest z NSIS 2.46

5.1 Polecenia narzędziowe kompilatora


Polecenia te w funkcjonalności i zasadzie działania podobne są do poleceń preprocesora C. Pozwalają one na dołączanie plików, warunkową kompilację, kompresowanie nagłówka pliku wykonywalnego oraz wykonywanie procesów podczas budowania instalatora. Uwaga: żadne z tych poleceń nie pozwalają na używanie zmiennych.


5.1.1 !include

[/NONFATAL] file

Polecenie !include dołącza plik 'file' do skryptu go wywołującego. Jeśli dołączany plik znajduje się w innym katalogu, bieżącym katalogiem jest wciąż ten, w którym skompilowany został skrypt (a nie ten, gdzie znajduje się dołączany plik). Jeśli kompilator nie może znaleźć pliku, będzie go szukał w każdym katalogu, w którym znajdują się dołączane pliki. Więcej informacji znajdziesz tutaj: !addincludedir. Jeśli używany jest przełącznik '/nonfatal' i nie znaleziono żadnych plików, wygenerowane zostanie ostrzeżenie zamiast błędu.

!include WinMessages.nsh
!include Library.nsh
!include C:\MojaKonfiguracja.nsi
!include ..\MojaKonfiguracja.nsh
!include /NONFATAL plik_ktory_istnieje_lub_nie.nsh



5.1.2 !addincludedir

directory

Polecenie !addincludedir dodaje kolejny katalog 'directory', w którym znajdują się dołączane pliki, do listy katalogów dołączanych do skryptu. Lista ta przeszukiwana jest po użyciu polecenia !include. Początkową wartością jest wartość '${NSISDIR}\Include'.

!addincludedir ..\include
!include jakisplik.nsh



5.1.3 !addplugindir

directory

Polecenie !addplugindir nakazuje kompilatorowi NSIS skanowanie podanego katalogu 'directory' w celu wyszukania wtyczek (bilbiotek DLL).

!addplugindir MojaWtyczka
MojaWtyczka::JakasFunkcja



5.1.4 !appendfile

file text

Polecenie !appendfile dodaje tekst text do pliku file.

!tempfile FILE
!appendfile "${FILE}" "XPStyle on$\n"
!appendfile "${FILE}" "Name 'test'$\n"
!include "${FILE}"
!delfile "${FILE}"
!undef FILE



5.1.5 !cd

new_path

Polecenie !cd zmienia katalog kompilatora na nowy katalog 'new_path'. Ścieżka katalogu 'new_path' może być względna lub bezwzględna.

!cd ..\wiecej-skryptow\nowy



5.1.6 !delfile

file

Polecenie !delfile usuwa plik 'file'.

!tempfile FILE
!delfile "${FILE}"
!undef FILE



5.1.7 !echo

message

Polecenie !echo wyświetli komunikat 'message' użytkownikowi kompilującemu skrypt.

!echo "Witaj świecie"



5.1.8 !error

[message]

Polecenie !error powoduje wyświetlenie błędu przez kompilator i zatrzymanie wykonywania skryptu. Możesz również dodać komunikat 'message' do tego błędu.

!ifdef VERSION & NOVERSION
  !error "Zarówno VERSION jak i NOVERSION są już zdefiniowane"
!endif



5.1.9 !execute

command

Polecenie !execute wykona polecenie 'command' używając funkcji CreateProcess(). W przeciwieństwie do polecenia !system, nie używny jest procesor linii poleceń. W rezultacie, polecenia przekierowań wejścia/wyjścia oraz polecenia takie jak 'cd', 'dir' oraz 'type' nie mogą być użyte. Polecenie !execute również ignoruje zwracaną wartość wykonanego polecenia 'command'. Obecnie, jedyną znaną przewagą polecenia !execute nad poleceniem !system jest to, że nie powoduje ono problemów, gdy bieżący katalog roboczy jest określony przy użyciu UNC.

Na platformach POSIX, polecenie !execute wykorzysta system(), jak tutaj: !system.

!execute '"%WINDIR%\notepad.exe" "${NSISDIR}\license.txt"'



5.1.10 !packhdr

tempfile command

Polecenie !packhdr pozwala kompilatorowi na użycie zewnętrznego kompresora pliku wykonywalnego EXE (takiego jak Petite lub UPX), które kompresują nagłówek pliku wykonywalnego. Określ nazwę pliku tymczasowego 'tempfile' (na przykład "temp.dat") oraz linię polecenia 'command' (na przykład "C:\program files\upx\upx -9 temp.dat"), aby skompresować nagłówek.

!packhdr "$%TEMP%\exehead.tmp" '"C:\Program Files\UPX\upx.exe" "$%TEMP%\exehead.tmp"'



5.1.11 !system

command [compare comparevalue]

Polecenie !system wykona polecenie 'command', używając wywołania funkcji system(). Jeśli zwrócona wartość porównania (używajac porównanie 'compare') z wartością porównywaną 'comparevalue' przyjmuje wartość False (Fałsz), wykonanie zostanie zatrzymane. Parametr 'compare' może mieć wartość: '<' lub '>' lub '<>' lub '='.

!system '"%WINDIR%\notepad.exe" "${NSISDIR}\license.txt"'
!system 'echo !define Cos > newinclude.nsh'
!include newinclude.nsh
!ifdef Cos
  !echo "Cos jest zdefiniowane"
!endif



5.1.12 !tempfile

symbol

Polecenie !tempfile tworzy plik tymczasowy. Wstawia ścieżkę dostępu do definicji, nazwanej 'symbol'.

!tempfile PACKHDRTEMP
!packhdr "${PACKHDRTEMP}" '"C:\Program Files\UPX\upx.exe" "${PACKHDRTEMP}"'
!tempfile FILE
!define /date DATE "%H:%M:%S %d %b, %Y"
!system 'echo Utworzono: ${DATE} > "${FILE}"'
File /oname=build.txt "${FILE}"
!delfile "${FILE}"
!undef FILE
!undef DATE



5.1.13 !warning

[message]

Polecenie !warning wygeneruje ostrzeżenie dla kompilatora skryptu. Możesz dodać również komunikat 'message' do tego ostrzeżenia.

!ifdef USE_DANGEROUS_STUFF
  !warning "Używam niebezpiecznych danych"
!endif



5.1.14 !verbose

level | push | pop

Polecenie !verbose ustala szczegółowość zwracanych komunikatów:

  • 4 = wszystkie komunikaty
  • 3 = bez skryptu
  • 2 = bez informacji
  • 1 = bez ostrzeżeń
  • 0 = brak komunikatów

Parametr 'push' spowoduje, że polecenie !verbose ustawi szczegółowość zwracanej wartości 'level' na specjalny stos. Parametr 'pop' zaś spowoduje to, że polecenie !verbose użyje bieżącego ustawienia szczegółowości zwracanej wartości 'level' ze stosu i użyje tego ustawienia.

!verbose push
!verbose 1
!include WinMessages.nsh
!verbose pop


5.2 Predefinicje


Możesz użyć tych standardowych predefinicji, aby automatycznie dodać czas zbudowania instalatora do linii z numerem wersji produktu oraz datę do numeru wersji, itp.


5.2.1 ${__FILE__}


Bieżąca nazwa skryptu.




5.2.2 ${__LINE__}


Bieżący numer linii.




5.2.3 ${__DATE__}


Data rozpoczęcia kompilacji skryptu, zgodna z lokalną datą.




5.2.4 ${__TIME__}


Czas rozpoczęcia kompilacji skryptu, zgodny z lokalnym czasem.




5.2.5 ${__TIMESTAMP__}


Data oraz Czas ostatniej modyfikacji pliku skryptu, zgodnie z lokalną datą i czasem.




5.2.6 ${NSIS_VERSION}


Wersja kompilatora NSIS, który został użyty do kompilacji skryptu.




5.2.7 Predefinicje zakresu


Standardowe predefinicje, które zawierają informację o zakresie bieżącego kodu.


5.2.7.1 ${__GLOBAL__}


Definiuje zakres globalny.

Section test

  !ifdef ${__GLOBAL__}
    !error "Ten tekst nie powinien się tutaj pojawić!"
  !endif

SectionEnd

Function test

  !ifdef ${__GLOBAL__}
    !error "Ten tekst nie powinien się tutaj pojawić!"
  !endif

FunctionEnd

PageEx instfiles

  !ifdef ${__GLOBAL__}
    !error "Ten tekst nie powinien się tutaj pojawić!"
  !endif

PageExEnd

5.2.7.2 ${__SECTION__}


Zdefiniowana jako nazwa sekcji, bez przedrostka, w zakresie kodu sekcji.

!ifdef __SECTION__
  !error "Ten tekst nie powinien się tutaj pojawić!"
!endif

Section test

  !ifndef __SECTION__
    !error "Brak predefinicji!"
  !endif

  !if ${__SECTION__} != test
    !error "Nieprawidłowa wartość predefinicji!"
  !endif

SectionEnd

Section !test

  !if ${__SECTION__} != test
    !error "Nieprawidłowa wartość predefinicji!"
  !endif

SectionEnd

Section un.test

  !if ${__SECTION__} != test
    !error "Nieprawidłowa wartość predefinicji!"
  !endif

SectionEnd

5.2.7.3 ${__FUNCTION__}


Zdefiniowana jako nazwa funkcji, bez przedrostka, w zakresie kodu funkcji.

!ifdef __FUNCTION__
  !error "Ten tekst nie powinien się tutaj pojawić!"
!endif

Function test

  !ifndef __FUNCTION__
    !error "Brak predefinicji!"
  !endif

  !if ${__FUNCTION__} != test
    !error "Nieprawidłowa wartość predefinicji!"
  !endif

FunctionEnd

Function un.test

  !if ${__FUNCTION__} != test
    !error "Nieprawidłowa wartość predefinicji!"
  !endif

FunctionEnd

5.2.7.4 ${__PAGEEX__}


Zdefiniowana jako typ strony w zakresie kodu PageEx.

!ifdef __PAGEEX__
  !error "Ten tekst nie powinien się tutaj pojawić!"
!endif

PageEx instfiles

  !ifndef __PAGEEX__
    !error "Brak predefinicji!"
  !endif

  !if ${__PAGEEX__} != instfiles
    !error "Nieprawidłowy typ strony"
  !endif

PageExEnd

5.2.7.5 ${__UNINSTALL__}


Zdefiniowana w zakresie kodu deinstalatora sekcji, funkcji lub strony PageEx.

!ifdef __UNINSTALL__
  !error "Ten tekst nie powinien się tutaj pojawić!"
!endif

Function test

  !ifdef __UNINSTALL__
    !error "Ten tekst nie powinien się tutaj pojawić!"
  !endif

FunctionEnd

Function un.test

  !ifndef __UNINSTALL__
    !error "Brak predefinicji!"
  !endif

FunctionEnd



5.3 Odczyt zmiennych środowiskowych


5.3.1 $%envVarName%


Zmienna $%envVarName% zostanie zastąpiona podczas kompilacji przez zmienną środowiskową envVarName.



5.4 Kompilacja warunkowa


Kompilator posiada wbudowaną listę zdefiniowanych symboli, które mogą być definiowane przy użyciu polecenia '!define' lub przełącznika w lini poleceń '/D'. Te zdefiniowane symbole mogą być używane w kompilacji warunkowej (dzięki użyciu polecenia '!ifdef') lub w celu zastępowania symboli (prosta forma makr). Aby zastąpić symbol daną wartością, użyj ${SYMBOL} (SYMBOL musi być zdefiniowany). Zastępowanie to działa na zasadzie: first-come-first-served (przetwarzany jest pierwszy element):

!define symbol_one ${symbol_two}

Jeśli symbol drugi 'symbol_two' jest zdefiniowany w tej lini, zostanie on zastąpiony. W przeciwnym razie zostaną zastąpione wszystkie wystąpienia symbolu pierwszego ${symbol_one}.

Polecenia związane z definicjami/kompilacją warunkową:


5.4.1 !define

([/date|/utcdate] gflag [value]) | (/math gflag val1 OP val2) | (/file gflag filename.txt)

Polecenie !define dodaje parametr gflag do globalnej listy definicji. Odniesie to podobny efekt jak użycie przełącznika /D w linii poleceń (tylko po poleceniu !define).

Jeśli parametry /date lub /utcdate są użyte, wartość value zostanie przekazana do funkcji strftime, a rezultat zostanie użyty jako wartość gflag. Polecenie strftime przekształca specjalne symbole w pewne części bieżącego czasu lub daty. Na przykład, symbol %H zostanie przekształcony w bieżącą wartość godziny w formacie 24-godzinnym. Pełna lista dostępnych symboli funkcji strftime dostępna jest na MSDN. Na platformach POSIX, możesz pobrać tę listę używając polecenia man strftime.

Jeśli użyty jest parametr /math zwrócona wartość 'val1 OP val2', gdzie OP może przyjmować wartości: +,-,*,&,|,^,/ lub %, zostanie użyta jako wartość gflag. Zauważ, że parametry val1 ORAZ val2 MUSZĄ być wartościami typu całkowitego!

Jeśli użyty jest parametr /file, cały plik (włącznie z białymi znakami i znakami nowej linii) zostanie odczytany i przekazany do gflag.

!define USE_SOMETHING
!define VERSION 1.2
!define /date NOW "%H:%M:%S %d %b, %Y"
!define /math RESULT 3 + 10
!define /math REST 15 % ${RESULT}
!define /file BUNCHASTUFF somesourcefile.cpp



5.4.2 !undef

gflag

Polecenie !undef usuwa wpis z globalnej listy definicji. Zauważ że, ${SYMBOL}, który nie jest zdefiniowany, zostanie przekształcony na "${SYMBOL}".

!define SOMETHING
!undef SOMETHING



5.4.3 !ifdef

gflag [bcheck gflag [...]]]

Polecenie !ifdef w połączeniu z poleceniem !endif, instruuje kompilator czy kompilowany ma być kod pomiędzy dwoma określonymi liniami. Jeśli parametr 'gflag' jest zdefiniowany globalnie (poprzez polecenie !define lub przełącznik /D), to linie z tego określonego zakresu zostaną skompilowane. W przeciwnym razie, zostaną one pominięte. Parametr 'bcheck' może być określony jako & (logiczne and) lub | (logiczne or) z więcej niż jednym parametrem gflag -- w kolejności z lewej do prawej.

!define SOMETHING
!ifdef SOMETHING
  !echo "SOMETHING jest zdefiniowane"
!endif
!undef SOMETHING
!ifdef SOMETHING
  !echo "SOMETHING jest zdefiniowane" # nie zostanie wypisane
!endif



5.4.4 !ifndef

gflag [bcheck gflag [...]]]

Polecenie !ifndef jest przeciwieństwem polecenia !ifdef. Linie zostaną skompilowane tylko wtedy, gdy parametr gflag nie został zdefiniowany.




5.4.5 !if

[!] value [op value2]

Polecenie !if, w połączeniu z poleceniem !endif, instruuje kompilator czy kompilowany ma być kod pomiędzy dwoma określonymi liniami. Jeśli parametr 'value' jest niezerowy, lub wynik porównania parametru 'value' oraz 'value2' będzie True (prawda), to linie z tego określonego zakresu zostaną skompilowane. W przeciwnym razie, zostaną one pominięte. Wartość 'op' może być zarówno == lub != (porównywanie łańcuchów znaków), <=, < > lub >= (porównywanie liczb zmiennoprzecinkowych), && lub || (porównywanie logiczne). Jeśli parametr [!] jest ustawiony, zwracana wartość będzie przełączona z prawdy na fałsz i na odwrót.

!if 1 < 2
  !echo "1 jest mniejsze od 2!!"
!else if ! 3.1 > 1.99
  !error "Ta linia nie powinna się pojawić"
!else
  !error "Jak i ta"
!endif



5.4.6 !ifmacrodef

gflag [bcheck gflag [...]]]

Polecenie !ifmacrodef, w połączeniu z poleceniem !endif, instruuje kompilator czy kompilowany ma być kod pomiędzy dwoma określonymi liniami. Jeśli parametr 'gflag' istnieje, to linie z tego określonego zakresu zostaną skompilowane. W przeciwnym razie, zostaną one pominięte. Parametr 'bcheck' może być określony jako & (logiczne and) lub | (logiczne or) z więcej niż jednym parametrem gflag -- w kolejności z lewej do prawej.

!macro JakiesMakro
!macroend
!ifmacrodef JakiesMakro
  !echo "JakiesMakro jest zdefiniowane"
!endif



5.4.7 !ifmacrondef

gflag [bcheck gflag [...]]]

Polecenie !ifmacrondef jest przeciwieństwem polecenia !ifmacrodef. Linie zostaną skompilowane tylko wtedy, gdy parametr gflag nie został zdefiniowany.




5.4.8 !else

[if|ifdef|ifndef|ifmacrodef|ifmacrondef [...]]

Polecenie !else pozwala na łatwe wstawianie innego kodu, gdy ustawione są inne definicje lub makra. Możesz tworzyć bloki kodu, takie jak !ifdef/!else/!endif, !ifdef/!else ifdef/!else/!endif itp.

!ifdef VERSION
OutFile installer-${VERSION}.exe
!else
OutFile installer.exe
!endif



5.4.9 !endif


Polecenie !endif zamyka blok rozpoczęty poleceniami !if, !ifdef, !ifndef, !ifmacrodef lub !ifmacrondef.




5.4.10 !insertmacro

macro_name [parameter] [...]

Polecenie !insertmacro wstawia zawartość makra, które zostało utworzone polecenim !macro. Jeśli makro zostało utworzone z parametrami, musisz przekazać tyle parametrów makra, ile jest wymagane.

!macro WydrukujTekst
  DetailPrint "${text}"
!macroend
!insertmacro Print "jakiś tekst"
!insertmacro Print "więcej tekstu"



5.4.11 !macro

macro_name [parameter][...]

Polecenie !macro tworzy makro o nazwie 'macro_name'. Wszystkie linie pomiędzy !macro oraz !macroend zostaną zapisane. Aby wstawić makro później, użyj polecenia !insertmacro. Definicje !macro mogą mieć jeden lub więcej zdefiniowanych parametrów. Dostęp do parametrów jest taki sam jak dla !define (np. ${PARMNAME}) z wnętrza makra.

!macro Jakiesmakro parm1 parm2 parm3
  DetailPrint "${parm1}"
  MessageBox MB_OK "${parm2}"
  File "${parm3}"
!macroend



5.4.12 !macroend


Polecenie !macroend kończy makro, które zostało rozpoczęte poleceniem !macro.




5.4.13 !searchparse

[/ignorecase] [/noerrors] [/file] 
source_string_or_file substring_start OUTPUTSYMBOL1 [substring [OUTPUTSYMBOL2 [substring ...]]]

Polecenie !searchparse przetwarza ciąg source_string_or_file (który jest traktowany jako ciąg znaków lub nazwa pliku, jeśli zdefiniowany jest parametr /file), wyszukując ciągu znaków substring_start. Jeśli ciąg znaków substring_start zostanie znaleziony, dla reszty ciągu definiowany jest parametr OUTPUTSYMBOL1 (minus dowolny inny ciąg substring, który może być znaleziony). Określona może być dowolna liczba parametrów OUTPUTSYMBOLx, a końcowy ciąg substring jest opcjonalny.

Jeśli zdefiniowany jest parametr /noerrors, dozwolone jest wyszukiwanie mniejszej liczby ciągów (wszystkie parametry OUTPUTSYMBOLx po nieprzeszukiwanym podciągu zostaną zignorowane).

Jeśli zdefiniowany jest parametr /file, plik traktowany jest jako ciąg linii. Plik jest przeszukiwany, dopóki znalezione zostaną wszystkie pasujące podciągi. Jeśli zdefiniowany jest parametr /noerrors i nie wszystkie ciągi zostały znalezione, pierwsza linia z największą liczbą pasujących symboli zostanie użyta.

# Przeszukuje plik filename.cpp na obecność linii: '#define APP_VERSION "2.5"' i ustawia wartość
# zmiennej ${VER_MAJOR} na 2 oraz wartość zmiennej ${VER_MINOR} na 5.
!searchparse /file filename.cpp `#define APP_VERSION "` VER_MAJOR `.` VER_MINOR `"`



5.4.14 !searchreplace

[/ignorecase] symbol_out source_string searchfor replacewith

Polecenie !searchreplace przeszukuje ciąg znaków source_string, w poszukiwaniu ciągu znaków searchfor oraz zamienia wszystkie jego znalezione wystąpienia ciągiem znaków replacewith. W przeciwieństwie do polecenia !define, polecenie !searchreplace pozwala na redefinicję parametru symbol_out bez komunikatu ostrzegawczego lub komunikatu o błędzie.

# zmienna ${blah} będzie miała wartość "Lubię kucyki"
!searchreplace blah "Kocham kucyki" "Kocham" "Lubię"