5. Polecenia kompilacji

Ten dokument zgodny jest z NSIS 3.1


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.

Literały liczbowe obsługują prefiksy radix 0b, 0o, 0n oraz 0x (odpowiednio z podstawą 2, 8, 10 oraz 16). Uwaga: Przestarzały zwykły ósemkowy prefiks 0 jest również obsługiwany w niektórych miejscach, ale jego użycie nie jest zalecane.


5.1.1 !include


[/NONFATAL] [/CHARSET=ACP|OEM|CP#|UTF8|UTF16LE|UTF16BE] 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. Przełącznik /charset może być użyty do określenia strony kodowej plików tekstowych, które nie zawierają znacznika BOM.

!include WinMessages.nsh
!include Library.nsh
!include /CHARSET=CP1252 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


[/x86-ansi | /x86-unicode] directory

Polecenie !addplugindir nakazuje kompilatorowi NSIS przeszukiwanie podanego katalogu directory w celu wyszukania wtyczek (bilbiotek DLL). Jeśli nie zostanie określona architektura wtyczek zastosowana zostanie bieżąca architektura docelowa. Jeśli określona architektura jest nieprawidłowa instalator prawdopodobnie zawiesi się!

!addplugindir MojaWtyczka
MojaWtyczka::JakasFunkcja


5.1.4 !appendfile


[/CHARSET=ACP|OEM|CP#|UTF8[SIG]|UTF16<LE|BE>[BOM]] [/RawNL] file text

Polecenie !appendfile dodaje tekst text do pliku file. Plik tekstowy zapisywany jest z kodowaniem ANSI (ACP), chyba że plik posiada już znaczik BOM. Używając przełącznika /CHARSET możesz ustawić określony sposób kodowania znaków. W systemie Windows, jeśli nie użyjesz przełącznika /RawNL, znaki $\n zostaną zamienione na znaki $\r$\n.

!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 [compare comparevalue | symbol]

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. 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 !makensis


parameters [compare comparevalue | symbol]

Polecenie !makensis wywołuje nową instancję programu MakeNSIS z odpowiednimi parametrami, używając polecenia !execute.

!makensis '-DGENERATEUNINST "${__FILE__}"' = 0
!system '"signtool" sign ...' = 0


5.1.11 !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.12 !finalize


command

Polecenie !finalize wykona polecenie command używając wywołania funkcji system(), po utworzeniu wyjściowego pliku EXE. Zazwyczaj możesz użyć tego polecenia do podpisania (Authenticode) instalatora. Jeśli parametr command zawiera '%1' zostanie on zastąpiony przez nazwę pliku wykonawczego.

!finalize 'sign.bat "%1" "Instalator produktu" http://przykladowyadres.com'


5.1.13 !system


command [compare comparevalue | symbol]

Polecenie !system wykona polecenie command, używając wywołania funkcji system(). Możesz przechować wynikową wartość w definicji symbol lub zatrzymać wykonywanie, jeśli zwrócona wartość porównania compare z comparevalue jest fałszywa. 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.14 !tempfile


symbol

Polecenie !tempfile tworzy plik tymczasowy. Ścieżka dostępu do tego pliku tymczasowego umieszczana jest w definicji 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.15 !getdllversion


localfilename define_basename

Polecenie to jest podobne do polecenia GetDLLVersionLocal. Różni się jednak tym, że wynikowy numer wersji przechowywany jest w definicji. W związku z tym polecenie to może być użyte wszędzie, nie tylko wewnątrz funkcji bądź sekcji.

!getdllversion "$%windir%\explorer.exe" expv_
!echo "Wersja programu Explorer.exe: ${expv_1}.${expv_2}.${expv_3}.${expv_4}"


5.1.16 !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.17 !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 z tego samego 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 ${__COUNTER__}


Wartość predefinicji zwiększa się do danej liczby (poczynając od 0 zwiększa się o 1 za każdym użyciem)



5.2.2 ${__FILE__}


Bieżąca nazwa skryptu.



5.2.3 ${__FILEDIR__}


Katalog bieżącego skryptu.



5.2.4 ${__LINE__}


Bieżący numer linii.



5.2.5 ${__DATE__}


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



5.2.6 ${__TIME__}


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



5.2.7 ${__TIMESTAMP__}


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



5.2.8 ${NSIS_VERSION}


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



5.2.9 ${NSIS_PACKEDVERSION}


Wersja NSIS w postaci liczby 32-bitowej.

!if 0x2046000 >= ${NSIS_PACKEDVERSION}
  !error "Aby utworzyć ten instalator wymagana jest wersja NSIS 2.47 lub nowsza!"
!endif


5.2.10 ${U+1}...${U+FFFFFFFF}


Znak Unicode (UCS-4).

!define U+ABC "SIS" # Definicja zostanie zastąpiona
DetailPrint "${U+2115}${U+ABC}" # DOUBLE-STRUCK CAPITAL N + "SIS"


5.2.11 Predefinicje zakresu


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


5.2.11.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.11.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.11.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.11.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.11.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.2.11.6 ${__MACRO__}


Zdefiniowana jako nazwa bieżącego makra.

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 linii 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} (jeśli SYMBOL nie jest zdefiniowany, zamiana nie nastąpi). 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}.


5.4.1 !define


[/ifndef | /redef] ([/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
!define /redef USE_SOMETHING ${RESULT} ; redefinicja USE_SOMETHING


5.4.2 !undef


gflag

Polecenie !undef usuwa wpis z globalnej listy definicji. Zauważ że, ${SYMBOL}, w którym SYMBOL 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]
[!] /FileExists "c:\path\file.exe"

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 bez uwzględniania wielkości liter), S== lub S!= (porównywanie łańcuchów znaków z uwzględnieniem wielkości liter), =, <>, <=, <, > lub >= (porównywanie liczb int/hex/float), & (porównywanie bitowego AND), && 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 < 0x2
  !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
!if /FileExists ".\cert.pfx"
  !finalize '".\sign.bat" "%1"'
!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 makro gflag nie istnieje.



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 Print text
  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 !macroundef


macro_name

Usuwa makro.



5.4.14 !searchparse


[/ignorecase] [/noerrors] [/file] src_str_or_file substr_start OUTPUTSYMBOL1 [substr [OUTPUTSYMBOL2 [substr ...]]]

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

Jeśli zdefiniowany jest parametr /noerrors, dozwolone jest wyszukiwanie mniejszej liczby łańcuchów znaków (wszystkie parametry OUTPUTSYMBOLx po podciągu, który nie został znaleziony, 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.15 !searchreplace


[/ignorecase] symbol_out source_string searchfor replacewith

Polecenie !searchreplace przeszukuje łańcuch znaków source_string, w poszukiwaniu łańcucha znaków searchfor oraz zamienia wszystkie jego znalezione wystąpienia łańcuchem 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ę"