Einleitung
Die meisten Anwendungen kommen mit einem Installations-Programm, das die benötigten Dateien in die richtigen Ordner kopiert, Registry-Einträge erstellt und Deinstallations-Routinen bereitstellt, um die Anwendung (hoffentlich) wieder sauber vom Computer zu entfernen.
Um selber entwickelte Anwendungen mit einem Installer auszustatten gibt es verschiedene Lösungen. Neben kommerziellen Produkten wie Install Shield oder Wise gibt es auch das OpenSource-Installationstool Nullsoft Scriptable Install System (NSIS). In diesem Tutorial zeige ich einige einfache Schritte, um einen Installer mit NSIS zu erstellen.
Im ersten Teil erläutere ich einige Grundlagen und wir erstellen den ersten richtigen Installer. Der zweite Teil behandelt die Themen Uninstall und weitere Dialoge für den Installer. Im dritten Teil gebe ich den Installern ein moderneres Erscheinungsbild.
Download und installation
NSIS kann unter http://nsis.sourceforge.net/Download heruntergeladen werden. Danach startet man die heruntergeladene Datei, welche NSIS installiert. Normalerweise können die vorgegebenen Werte übernommen werden.
Grundlagen
NSIS erzeugt eine Installationsdatei, die alle zu installierenden Dateien und das Installationsscript enthält. Dazu muss man ein NSIS Script erstellen, welches die Installationsschritte beschreibt. Ein NSIS Script ist eine normale Textdatei, die mit jedem Texteditor bearbeitet werden kann. Da NSIS bei Fehlermeldungen die betroffene Zeile angibt, ist es von Vorteil, einen Texteditor zu benutzen, der die Zeilennummern anzeigen kann.
Im Wiki von NSIS hat es eine Auflistung von Editoren speziell für NSIS. Ich benutze für dieses Tutorial den HM NIS Edit.
NSIS Script-Dateien haben die Dateiendung .nsi. NSIS Scripts können zur besseren Übersicht auch in mehrere Dateien aufgeteilt werden, indem man Funktionen oder Makros in Header-Dateien auslagert. Die Headerdateien erhalten dann die Dateiendung .nsh und werden mit dem Befehl !include
eingebunden.
Kommentare werden mit einem Semikolon – ‚;‘ – begonnen und enden mit dem Zeilenende. Auch alle Befehle enden mit dem Zeilenende. Wenn sich ein Befehl über mehrere Zeilen erstrecken soll muss am Zeilenende ein Backslash – ‚\‘ – hizugefügt werden.
Hello World!
Als erstes „Installer“-Script erstellen wir das berühmte „Hello World“ Beispiel. Dazu muss in einem Text-Editor folgender Text eingegeben werden:
OutFile "helloworld.exe"
Section "Hello World"
MessageBox MB_OK "Hello World!"
SectionEnd
Dieser Text wird nun unter dem Dateinamen „helloworld.nsi“ abgespeichert. Nun kann der Compiler gestartet werden. Entweder direkt über den Editor (z.B. mit HM NIS Edit) oder über die Kommandozeile mit:
Wenn das Script fehlerfrei kompiliert werden konnte sollte eine Datei mit dem Namen „helloworld.exe“ im Spriptordner erstellt worden sein. Durch Starten dieser Anwendung sollte ein Installer-Fenster erscheinen und davor eine MessageBox mit dem Text „Hello World!“.
Erklärung der benutzten Befehle:
Name
Setzt den Namen des Installers. Normalerweise entspricht er dem Namen der Anwendung, Z.B. „MyApp“. Wenn der Name ein oder mehrere ‚&‘ enthält, muss als zweiter Parameter der Name mit verdoppelten ‚&‘ angegeben werden, z.B.
OutFile
Setzt den Namen der Ausgabe-Datei. Kann auch den Pfad enthalten, z.B.
Section
Startet einen neuen Bereich. Bereiche können auch versteckt werden, optional sein oder für den Uninstaller verwendet werden. Der Bereich wird mit SectionEnd
abgeschlossen.
MessageBox
Zeigt ein Meldungsfenster mit den angegebenen Optinen („Zeige den OK-Button“) und dem angegebenen Text an.
Erster „richtiger“ Installer
Um auch wirklich etwas auf der Harddisk abzulegen braucht es nicht viel mehr:
OutFile "firstinstaller.exe"
InstallDir $PROGRAMFILES\MyFirstInstaller
Page directory
Page instfiles
Section ""
SetOutPath $INSTDIR
File C:\Windows\system32\notepad.exe
SectionEnd
Name
und OutFile
kennen wir ja schon aus dem HelloWorld-Installer. InstallDir
setzt den Default-Installationspfad. Mit der Konstanten $PROGRAMFILES
wird der konfigurierte Programme-Ordner (bei einer deutschen Windows-Version „C:\Programme\“, bei einer englischen „C:\Program files“) angesprochen. In diesem Beispiel wird deshalb als Default-Ordner unter einer deutschen Windows-Version „C:\Programme\MyFirstInstaller“ verwendet. Mit dem Befehl Page
geben wir an, welche Seiten im Installer angezeigt werden sollen. In diesem Fall wird zuerst der Dialog für die Installationsordner-Abfrage angezeigt. Danach folgt der eigentliche Installations-Dialog, in welchem die Dateien kopiert werden.
Innerhalb der Section
wird dann mit SetOutFolder
der Ordner für die Installation bestimmt und auch erzeugt. Mit File
werden die Dateien angegeben, die in den Installationsordner extrahiert werden sollen.
Ausblick
Im zweiten Teil werden wir unserem Installer auch die Möglichkeit geben, das Programm wieder zu deinstallieren. Zudem werden wir ein Paar weitere Pages anschauen und dem Benutzer die Möglichkeit geben, bestimmte Teile der Installation auszuwählen. Im dritten Teil werden wir dann ein dem Installer mit dem ModernUI ein moderneres Erscheinungsbild geben.
Pingback: Neues Design der Webseite | of bits and bytes
Pingback: NSIS Tutorial in c’t 16/2014 | of bits and bytes
Kann man nsis auch einsetzen für projekte, die in Visual Studio Express 2012 erstellt wurden?
Wenn ja, wie findet man heraus, welche Dateien notwendig sind?
Gruß Jürgen
Hallo Jürgen
NSIS ist nicht von der Entwicklungsumgebung oder der Programmiersprache abhängig. Wichtig ist nur, dass Du alle nötigen Dateien im Installer mitlieferst.
Um herauszufinden, welche Dateien nötig sind ist es dann relevant, mit welcher Programmiersprache die Anwendung geschrieben wurde. Wenn Du Visual Studio erwähnst, nehme ich an, dass es entweder C++, VB.NET oder C# sein dürfte.
Bei C++ kann Dir das Tool Dependency Walker weiterhelfen. Bei einer .NET-Anwendung ist es wichtig, dass das .NET-Framework in der passenden Version installiert ist und die zusätzlichen Referenzen (z.B. log4net etc.) durch NSIS installiert werden.
Hilfe zum Einbinden des .NET-Framework-Installers in NSIS findest Du im NSIS-Wiki.
Ich hoffe, Dir damit weiter geholfen zu haben.
selbstverständlich. Du musst in deinem visualstudiprojekt in den Release-Mode wechseln. Anschließend debbugst du das Projekt. Danach finden sich die benötigten Dateien in dem Releaseordner. Hier mal kleiner Aufbau eines Programmes.
Name „test v1.1 Setup“
OutFile „testSetup.exe“
!define INSTALLATIONNAME „Testprogramm“
InstallDir $PROGRAMFILES\${INSTALLATIONNAME} ;Speichert Inhalt in C:\Programme 86\Testprogramm
Page directory
Page instfiles
Section „“
SetOutPath $INSTDIR ;kopiert alle nachfolgenden Dateien in den Ornder $INSTDIR. (also C:\Programme 86\Testprogramm)
File ..\HelloWorld\bin\Release\HelloWorld.exe
File ..\HelloWorld\bin\Release\HelloWorld.exe.config
File ..\HelloWorld\bin\Release\HelloWorld.vshost.exe.config
;File ..\HelloWorld\bin\Release\app.config
;File ..\HelloWorld\bin\Release\log4net.dll ;verwendete .dll auch mit einbinden
;Verknüpfungen Desktop/Startmenü
CreateShortCut „$DESKTOP\${Installationname}.lnk“ „$INSTDIR\HelloWorld.exe“ „“
CreateDirectory „$SMPROGRAMS\${INSTALLATIONNAME}“
CreateShortCut „$SMPROGRAMS\${INSTALLATIONNAME}\${Installationname}.lnk“ „$INSTDIR\HelloWorld.exe“ „“ „$INSTDIR\HelloWorld.exe“ 0
SectionEnd
Das wars. Kopier den Inhalt in eine .txt-Datei und benenne sie „meinSkript.nsi“. Damit der Installer die Dateien auch finden kann muss dein Projektordner so aufgebaut sein:
Erstelle einen Ordner mit dem Namen „Installer“. In diesem fügst du die meinSkript.nsi-Datei ein. Der Ordner „Installer“ muss im selben Ordner liegen, wie der Ordner „HelloWorld“. Dann funktioniert es. Die Funktion File .. bezieht sich irgendwie auf den Ordnerpfad, in dem der Installer ausgeführt wird. Falls du es nicht hinbekommst, kannst du auch feste Pfade verwenden z.b. File C:\USER\Desktop\MeinProgramm\HelloWorld\bin\Release\..
Klicke mit Rechtsklick auf das Skript und wähle die Funktion „Compile NSIS Scirpt“. Anschließend öffnet sich ein Fenster, der dir anzeigt, was passiert. Ist beim Übersetzten ein Fehler aufgetreten, so wird er dort angezeigt. Anschließend starte die testSetup.exe. (als Admin, wenn du Schreibrechte benötigtst). Anschließend kopiert er die alle Dateien , die du mit File .. angegeben hast, in das Installationsverzeichnis und erstellt auf dem Desktop sowie im Startmenü eine Verknüpfung.
Nun müsste dein Visualstudioprojekt ausführbar sein. Wenn nicht, fehlen dir noch Dateien, wie .dll’s.
Kann man regFiles so einbinden, dass sie die Registry ohne Rückfrage modifizieren?
Der bevorzugte Weg um Registry-Einträge mit NSIS zu erstellen ist mit den WriteReg…-Instruktionen (siehe z.B. NSIS Scripting Reference Chapter 4).
Falls ein existierendes .reg-File eingelesen werden soll, kann dies über regedit.exe erfolgen. Mit dem Parameter /s können dabei Meldungen unterdrückt werden (siehe auch die Microsoft Dokumentation zu Regedit).
Der Aufruf auf der Kommandozeile würde dann wie folgend aussehen:
regedit /s MeinRegistryFile.reg
bzw. wenn der Aufruf aus einem NSIS-Script heraus erfolgen soll:
ExecWait ‚regedit /s MeinRegistryFile.reg‘
Pingback: Zeitgeist 2020 | of bits and bytes
Hallo Roland,
mein Problem
;Wenn die Exe und die Dlls auf meinem alten PC (XP) einkopiert werden soll
;funktioniert das
;————————————————————-
;!define SOURCEPATH „C:\Programme\Microsoft Visual Studio\MyProjects“
;FILE /r „${SOURCEPATH}\HomeLab\Release\HomeLab.exe“
;FILE /r „${SOURCEPATH}\HomeLab\Release\sys-homeLab.bmp“
;FILE /r „${SOURCEPATH}\AppTempDll.dll“
;FILE /r „${SOURCEPATH}\AppTempKeyDll.dll“
;FILE /r „${SOURCEPATH}\AppTempPngDll.dll“
;FILE /r „${SOURCEPATH}\AppPictDll.dll“
;File /r „C:\Dokumente und Einstellungen\Anwender\Eigene Dateien\HomeLab\License.txt“
;Wenn die Exe und die Dlls auf meinem Labtop (Windows 10) einkopiert werden soll
;funktioniert das nicht -> no files found
;————————————————————-
;!define SOURCEPATH-1 „C:\Benutzer\Anwender\source\repos\myHomeLab\Release“
;FILE /r „${SOURCEPATH-1}\myHomeLab.exe“
;FILE /r „${SOURCEPATH-1}\sys-homeLab.bmp“
;FILE /r „${SOURCEPATH-1}\AppTempDll.dll“
;FILE /r „${SOURCEPATH-1}\AppTempKeyDll.dll“
;FILE /r „${SOURCEPATH-1}\AppTempPictureDll.dll“
;!define SOURCEPATH-2 „C:\Benutzer\Anwender\documents“
;File /r „${SOURCEPATH-2}\HomeLab\License.txt“
;Wenn die Exe und die Dlls vom Laufwerk E: einkopiert werden
;funktioniert das (OK)
;————————————————————-
!define SOURCEPATH-2 „E:\Install“
FILE /r „${SOURCEPATH-2}\myHomeLab.exe“
FILE /r „${SOURCEPATH-2}\sys-homeLab.bmp“
FILE /r „${SOURCEPATH-2}\AppTempDll.dll“
FILE /r „${SOURCEPATH-2}\AppTempKeyDll.dll“
FILE /r „${SOURCEPATH-2}\AppTempPictureDll.dll“
File /r „${SOURCEPATH-2}\License.txt“
Hallo Friedrich
Meine Vermutung, ohne dies aber getestet zu haben, wäre, dass dies mit den übersetzten Ordnernamen zu tun hat, die Windows 10 verwendet. Der im Explorer angezeigte Ordnername C:\Benutzer\ existiert nicht im Filesystem, dort heisst er C:\Users\. Vermtulich wird dies in NSIS nicht entsprechend behandelt und deshalb können die Dateien nicht gefunden werden.
Ich würde dir empfehlen mit relativen Pfaden zu arbeiten. Normalerweise gehört ein Installer zu einem bestimmten Programm, das du entwickelt hast. Wenn du das Installerscript entsprechend mit dem Sourcecode des Programmes zusammen behandelst kannst du die gesamte Ordnerstruktur irgendwo ablegen und das Projekt kann immer so gebaut werden.
Ausgehend von deinem Beispiel oben wäre /myHomeLab/ dein Projektordner. In diesem könntest du das Installerscript in einem Unterordner Installer speichern. Dann müssten die FILE-Anweisungen wir folgt aufgebaut sein:
FILE ..\Release\myHomeLab.exe
FILE ..\Release\sys-homeLab.bmp
etc.
Ich hoffe, dir damit geholfen zu haben.
Viele Grüsse
Roland