In diesesm Tutorial beschreibe ich, wie man (mehr oder weniger) einfach mit dem NSIS Installer für seine Scripte/Mods schreibt.
Der Weg über einen NSIS-Installer hat gegenüber dem Plugin Manager oder einer manuellen Verteilung in zip/rar/7z-Archiven den Vorteil, dass der Benutzer keinerlei Zusatzprogramme braucht. Da der NSIS die selbe Kompressionsmethode wie 7zip benutzt, sind die damit gepackten Archive zudem sehr kompakt.
Nachteil gegenüber dem Plugin Manager ist, dass hierbei nur komplette Dateien ersetzt werden können und keine Kollisionserkennung möglich ist. Hiermit erstellte Archive sind an das normale cat/dat-Archiv gebunden, mit den damit verbundenen Kompatibilitätsproblemen.
Ein Beispiel dafür, was mit dem NSIS möglich ist, ist mein HUD-Mod: http://forum.egosoft.com/viewtopic.php?t=221008 Der NSIS ermöglicht es hier, dass beliebige Kombinationen von cats/dats in korrekter Nummerierung als Fakepatch installiert werden, und über die Systemsteuerung deinstalliert werden können.
Vorbereitung: Notwendige Programme, Konventionen
Was ihr auf jeden Fall braucht, ist der NSIS selber: http://nsis.sourceforge.net/Download
Bei der Komponentenauswahl während der Installation achtet darauf, dass ihr das „Modern User Interface“, die „Language Files“ sowie „Language DLL“, „nsDialog“ und „nsExec“ mitinstalliert.
Zudem zwingend benötigt wird ein Texteditor. Notepad tuts zur Not auch, etwas komfortabler ist Notepad++ (http://notepad-plus.sourceforge.net/de/ ... hp?lang=de).
Optional ist ein Grafikbearbeitungsprogramm wie GIMP oder Paint.NET, falls ihr eurem Installer eigene Icons hinzufügen wollt.
Information zu meinem Schreibstil: Quelltexte in Code-Blöcken können 1:1 kopiert und ausprobiert werden. Platzhalter sind entweder mit <> gekennzeichnet (<schlauen Kommentar hier einfügen>), bei Beispielen benutze ich als Platzhalter „foo“, „bar“, „bla“ und ähnliches – das ist ebenfalls ersetzbar.
Einführung
Die Anweisungen, wie der Installer auszusehen hat, werden in .nsi-Dateien geschrieben und dann mit dem Programm „makensisw“ kompiliert. Die .nsi-Dateien sind einfache Textdateien und können daher mit einem beliebigen Texteditor bearbeitet werden.
NSI-Dateien bestehen aus mehreren Abschnitten: Die eigentlichen Informationen, welche Dateien wohin installiert werden, sind in sogenannten „Sections“:
Code: Select all
Section "<Name>" <ID>
; Hier stehen die Anweisungen
SectionEnd
Sektionen erscheinen auch als an- bzw. abwählbare Option im Installer. Der Name der Sektion wird bei dieser Auswahl angezeigt, im Installer intern wird die ID verwendet. Der Name muss daher nicht zwangsläufig vergeben werden.
Neben Sektionen gibt es noch Funktionen, die vom Installer nicht angezeigt werden, und manuell aufgerufen werden können:
Code: Select all
Section Foo
Call Bar ; ruft die Funktion Bar auf
SectionEnd
Function Bar
;Hier die Anweisungen
FunctionEnd
Diese Optionen sind unabhängig von den einzelnen Sektionen. Teilweise sind es Anweisungen für den makensisw-Compiler, wie er die Datei handzuhaben hat, teilweise sind es Einstellungen des Installers. Hier die wichtigsten:
Code: Select all
OutFile "<Name>.exe" ; Der Name der fertigen Installer-Datei
RequestExecutionLevel admin ; Für Vista relevant: Installation benötigt Adminrechte
SetCompressor /SOLID lzma ; Legt die Kompression fest. LZMA benötigt mehr Zeit beim Kompilieren, erzeugt aber die kleinsten Archive.
InstallDir "$PROGRAMFILES\<Ordner>\" ; Das Zielverzeichnis. Kann vom User noch geändert werden
InstallDirRegKey HKLM "Software\<Pfad>" "" ; Damit wird das Zielverzeichnis in der Registry gespeichert und kann bei der Deinstallation ausgelesen werden.
Caption "<Titel>" ; Titel des Installers
BrandingText "<Name, Firma, URL oÄ>" ; Legt den Copyright-Text links unten fest.
Name "<Name>" ;Name des Installers, wird bpsw. auf der Begrüßungseite angezeigt
!include <lib>.nsh ; Hiermit werden zusätzliche Komponenten eingebunden.
Die Installation von Dateien ist recht einfach: Zuerst gebt ihr (in der Section) mit „SetOutPath“ an, wohin die Dateien installiert werden sollen, danach gebt ihr mit „File“ die Dateien an:
Code: Select all
OutFile test.exe
InstallDir "C:\foo"
Section Example
SetOutPath $INSTDIR
File readme.txt
WriteUninstaller $INSTDIR\foo.exe
SectionEnd
Section Uninstall ; den Namen NICHT ändern!
Delete $INSTDIR\readme.txt
Delete $INSTDIR\foo.exe
SectionEnd
BlingBling!
Bisher sieht der Installer nicht wirklich berauschend aus, das ändert sich jetzt mit der Einführung des Modern User Interface, kurz MUI. Das MUI verbessert viele Aspekte des NSIS und ist zudem halbwegs einfach zu handhaben, daher gehe ich gleich dazu über.
Das MUI wird per
Code: Select all
!include MUI2.nsh
Code: Select all
!define MUI_ICON <name>.ico ; Legt das Symbol des Installers fest
!insertmacro MUI_PAGE_DIRECTORY ; Gibt dem user die Möglichkeit, das Zielverzeichnis zu ändern
!insertmacro MUI_PAGE_COMPONENTS ; Bietet die Möglichkeit, einzelne Sektionen an- bzw. abzuwählen
!insertmacro MUI_PAGE_INSTFILES ; ACHTUNG: Dieses Macro muss IMMER eingebunden werden, wenn Dateien installiert werden sollen!
!insertmacro MUI_LANGUAGE "<Sprache>" ; Damit können mehrere Sprachen eingebunden werden - dazu später mehr
Ein einfacher einsprachiger Installer mit dem MUI:
Code: Select all
!include MUI2.nsh
OutFile test.exe
InstallDir "C:\foo"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
Section Example
SetOutPath $INSTDIR
File test.bmp
WriteUninstaller $INSTDIR\foo.exe
SectionEnd
Section Uninstall ; den Namen NICHT ändern!
Delete $INSTDIR\test.bmp
Delete $INSTDIR\foo.exe
SectionEnd
Das waren eigentlich schon die grundlegenden Befehle für den NSIS – einfache Installer für Scripte und Mods lassen sich so schon schreiben. Was jetzt kommt, sind die Feinheiten:
Mehrsprachige Installer
Um einen Installer vollständig mehrsprachig zu machen, sind einige Änderungen nötig:
Zuerst einmal werden die gewünschten Sprachen per
Code: Select all
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "German"
;...
Code: Select all
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
FunctionEnd
Das ist allerdings noch nicht alles, damit sind naturgemäß nur die „normalen“ Texte des Installers übersetzt. Um die Komponentennamen (und -beschreibungen) zu übersetzen, müssen diese als übersetzbare Strings eingebaut werden. Übersetzbare Strings sind Variablen, die per $(Name) eingesetzt und per „LangString“ übersetzt werden:
Code: Select all
Section $(example) Example
;...
SectionEnd
LangString example ${LANG_GERMAN} "Beispiel-Sektion"
LangString example ${LANG_ENGLISH} "Example Section"
LangString DESC_ex ${LANG_GERMAN} "Dies ist eine Beispielsektion."
LangString DESC_ex ${LANG_ENGLISH} "This is an example section."
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Example} $(DESC_ex)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Integration in die Systemsteuerung und zusätzliche Dateiattribute
Um in der Systemsteuerung angezeigt zu werden, muss der Installer etliche Registry-Keys setzen:
Code: Select all
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"DisplayName" "<Name>" ;angezeigter Name
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"UninstallString" "$INSTDIR\<Pfad zum Uninstaller>"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"Publisher" "<euer Name>"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"HelpLink" "<URL>"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"DisplayVersion" "<Version>"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"NoModify" 1 ; Keine nachträgliche Modifizierung möglich
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"NoRepair" 1 ; Keine Reparatur möglich
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"ParentDisplayName" "X3 Terran Conflict v1.0.1" ; Lässt den Mod als Update zu TC erscheinen
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\<Name>" \
"ParentKeyName" "X3TerranConflict_is1" ; Lässt den Mod als Update zu TC erscheinen
Der NSIS bietet zudem die Möglichkeit, beim Installer zusätzliche Dateiattribute wie die Version zu setzen. Das ist größtenteils Spielerei, aber bspw. die Angabe der Version kann ganz hilfreich sein:
Code: Select all
VIProductVersion <Version>
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "<Name>"
VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "<euer Name>"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "X³ Terran Conflict is a registered trademark of EGOSOFT. All rights reserved. <etc. pp.>"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "<Version>"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "<Beschreibung>"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© <Copyright>"
Automatisch die passenden cat/dat-Nummern auswählen
Diese Funktion ist für Fakepatches extrem praktisch, da hiermit die Nummern der Cats/Dats dynamisch bei der Installation festgelegt werden, wodurch es nicht zu unfreiwilligen Überschreibungen kommt. Dafür braucht ihr folgenden Codeschnipsel:
Code: Select all
!include LogicLib.nsh
Function .onInit
;Variable catnumber definieren
Var /GLOBAL catnum
StrCpy $catnum 6
Var /GLOBAL catcnt
; ...
FunctionEnd
Function catnums
${If} $catnum > 9
IfFileExists $INSTDIR\$catnum.cat 0 +3 ; Prüft die Katalognummern durch
IntOp $catnum $catnum + 1
Goto -2
${Else}
IfFileExists $INSTDIR\0$catnum.cat 0 +3 ; Prüft die Katalognummern durch
IntOp $catnum $catnum + 1
Goto -2
${EndIf}
IntOp $catcnt $catcnt + 1
FunctionEnd
Function SecDone
FileOpen $1 $INSTDIR\<Name eures Logfiles, sollte eindeutig und nur einmal vergeben sein> a
FileWrite $1 $catnum
FileWrite $1 "$\n"
FileWrite $1 $catcnt
FileClose $1
FunctionEnd
Section "Uninstall" ;deinstallieren
FileOpen $1 $INSTDIR\<Name eures Logfiles> r
FileRead $1 $2 ;höchste Cat-Nummer
FileRead $1 $3 ;Catanzahl
FileClose $1
IntOp $2 $2 + 1
IntOp $3 $3 + 1
${While} $3 > 0
${If} $2 > 9
Delete $INSTDIR\$2.cat
Delete $INSTDIR\$2.dat
${Else}
Delete $INSTDIR\0$2.cat
Delete $INSTDIR\0$2.dat
${EndIf}
IntOp $3 $3 - 1
IntOp $2 $2 - 1
${EndWhile}
SectionEnd
Damit eure Cats auch umbenannt werden, müssen eure Sections in der folgenden Art aufgebaut sein:
Code: Select all
Section Foo
SetOutPath $INSTDIR
Call catnums
File <Name>.cat
File <Name>.dat
${If} $catnum > 9
Rename $INSTDIR\<Name>.cat $INSTDIR\$catnum.cat
Rename $INSTDIR\<Name>.dat $INSTDIR\$catnum.dat
${Else}
Rename $INSTDIR\<Name>.cat $INSTDIR\0$catnum.cat
Rename $INSTDIR\<Name>.dat $INSTDIR\0$catnum.dat
${EndIf}
Call SecDone
SectionEnd
Schlusswort
Dieses Tutorial soll nicht sämtliche Feinheiten des NSIS erläutern, sondern nur einen Überblick geben, was damit alles möglich ist. Ich hoffe, ich konnte den einen oder anderen dazu bringen, sich etwas mehr mit dem Thema auseinander zu setzen. Auf dass wir bald Mods mit vernünftigen Installern haben. *g*
Für weiterführende Informationen verweise ich auf das Developer Center, das etliche Tutorials und Beispiele bereitstellt: http://nsis.sourceforge.net/Developer_Center
Fragen, Anmerkungen, Kommentare?
