Qt-Tutorial Teil 4: Kompilieren und Installation von Software unter Windows
Unter Windows ist es sinnvoll, ein Programm in Form eines Installationsprogramms anzubieten. In diesem Teil des Tutorials wird kurz auf das Zusammenspiel zwischen Qt und NSIS eingegangen.
Windows-Ressourcen
Im ersten Teil des Tutorials wurde die Projektdatei für qmake beschrieben. Zur Wiederholung sehen wir uns noch einmal den Windows-spezifischen Teil an:
- Quelltext: Alles auswählen | Zeilennummerierung an/aus
-
- win32 {
- message("Baue für Win.")
- #Ressourcen-Referenz (Textdatei)
- RC_FILE = win/myapp.rc
- }
Was verbirgt sich hinter der ominösen Ressourcen-Referenz?
Windows-exe-Dateien enthalten neben dem Programmcode sogenannte Ressourcen. Die bekanntesten Vertreter solcher Zusatzinformationen sind die Icons für das Programm. In der Ressourcen-Referenz werden solche Informationen für den Compiler definiert, damit er ein Windows-Programm samt Icons erstellen kann.
Die Ressourcen-Datei sieht im einfachsten Fall z.B. so aus:
- Quelltext: Alles auswählen | Zeilennummerierung an/aus
-
- IDI_ICON1 ICON DISCARDABLE "win/myIcons.ico"
Die Ressource verweist in diesem Fall auf eine Datei myIcons.ico, welche die Icons für die Applikation bereitstellt. Auf das Erstellen solcher Icon-Dateien unter Windows werde ich hier nicht eingehen – eine einfache Methode bietet beispielsweise das Freeware-Programm SimplyIcon.
Sowohl die Ressources-Datei als auch die Icons liegen im Unterverzeichnis win. Dies muss jedoch nicht so sein, räumt die Entwicklungsumgebung jedoch etwas auf.
Installer mit NSIS erstellen
Ein gutes Windowsprogramm wird mit einem Installer ausgeliefert. Dieser kümmert sich um das Installieren aller relevanten Dateien, sowie später auch um das saubere Löschen, falls das Programm wieder deinstalliert wird.
NSIS (Nullsoft Scriptable Install System) ist einer der populärsten Installer und wird auch im professionellen Bereich oft eingesetzt. NSIS ist Open Source und läuft im Übrigen auch unter Linux und Mac.
NSIS erwartet eine Installationsdatei. Diese ist eine einfache Textdatei mit entsprechenden Anweisungen. Wie diese Anweisungen aufgebaut sind, ist ebenfalls nicht Gegenstand dieses Tutorials – das Internet ist voll mit guten Tutorials zum Thema NSIS. Ein guter Einstieg für die Installation es Qt-Programms ist das folgende Skript:
- Quelltext: Alles auswählen | Zeilennummerierung an/aus
-
- !define VERSION "1.0.0"
- !define QT "C:\Qt\2010.02.1\qt\bin\"
- !define INSTALLATIONNAME "MyApplication"
- ;--------------------------------
- ;Include Modern UI
- !include "MUI2.nsh"
- ;--------------------------------
- ;General
- ;Name and file
- Name "${INSTALLATIONNAME} ${VERSION}"
- OutFile "MyApplication.exe"
- SetCompressor lzma
- ;Default installation folder
- InstallDir "$PROGRAMFILES\MyApplication"
- ;Get installation folder from registry if available
- InstallDirRegKey HKCU "Software\${INSTALLATIONNAME}" ""
- ;Request application privileges for Windows Vista
- !define MULTIUSER_EXECUTIONLEVEL Highest
- !define MULTIUSER_MUI
- !define MULTIUSER_INSTALLMODE_COMMANDLINE
- !include MultiUser.nsh
- ;--------------------------------
- ;Interface Settings
- !define MUI_HEADERIMAGE
- !define MUI_HEADERIMAGE_BITMAP "cm_header.bmp"
- !define MUI_HEADERIMAGE_UNBITMAP "cm_un-header.bmp"
- !define MUI_WELCOMEFINISHPAGE_BITMAP "cm_wizard.bmp"
- !define MUI_UNWELCOMEFINISHPAGE_BITMAP "cm_un-wizard.bmp"
- !define MUI_ICON "myIcons.ico"
- # !define MUI_UNICON "unicon.ico"
- !define MUI_ABORTWARNING
- ;Show all languages, despite user's codepage
- !define MUI_LANGDLL_ALLLANGUAGES
- ;--------------------------------
- ;Language Selection Dialog Settings
- ;Remember the installer language
- !define MUI_LANGDLL_REGISTRY_ROOT "SHCTX"
- !define MUI_LANGDLL_REGISTRY_KEY "Software\${INSTALLATIONNAME}"
- !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
- ;Start Menu Folder Page Configuration
- !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
- !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${INSTALLATIONNAME}"
- !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
- ;--------------------------------
- ;Pages
- !insertmacro MUI_PAGE_WELCOME
- !insertmacro MUI_PAGE_LICENSE $(license)
- !insertmacro MUI_PAGE_COMPONENTS
- !insertmacro MULTIUSER_PAGE_INSTALLMODE
- !insertmacro MUI_PAGE_DIRECTORY
- !insertmacro MUI_PAGE_INSTFILES
- !insertmacro MUI_PAGE_FINISH
- !insertmacro MUI_UNPAGE_WELCOME
- !insertmacro MUI_UNPAGE_CONFIRM
- !insertmacro MUI_UNPAGE_INSTFILES
- !insertmacro MUI_UNPAGE_FINISH
- ;--------------------------------
- ;Languages
- !insertmacro MUI_LANGUAGE "English" ;first language is the default Language
- !insertmacro MUI_LANGUAGE "German"
- ;--------------------------------
- ;Reserve Files
- ;If you are using solid compression, files that are required before
- ;the actual installation should be stored first in the data block,
- ;because this will make your installer start faster.
- !insertmacro MUI_RESERVEFILE_LANGDLL
- ;--------------------------------
- ;Installer Sections
- Section ""
- SetOutPath $INSTDIR
- File ..\Release\MyApplication.exe
- File ..\*.qm
- File license*.rtf
- File ${QT}mingwm10.dll
- File ${QT}libgcc_s_dw2-1.dll
- File ${QT}QtCore4.dll
- File ${QT}QtGui4.dll
- WriteUninstaller $INSTDIR\uninstall.exe
- WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLATIONNAME}" "DisplayName" "Forth Installer"
- WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLATIONNAME}" "UninstallString" '"$INSTDIR\uninstall.exe"'
- WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLATIONNAME}" "NoModify" 1
- WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLATIONNAME}" "NoRepair" 1
- WriteRegStr SHCTX "Software\${INSTALLATIONNAME}" "" $INSTDIR
- SectionEnd
- Section $(startmenu) Startmenu
- CreateDirectory "$SMPROGRAMS\${INSTALLATIONNAME}"
- CreateShortCut "$SMPROGRAMS\${INSTALLATIONNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
- CreateShortCut "$SMPROGRAMS\${INSTALLATIONNAME}\MyApplication.lnk" "$INSTDIR\MyApplication.exe" "" "$INSTDIR\MyApplication.exe" 0
- SectionEnd
- Section /o $(desktop) Desktop
- CreateShortCut "$DESKTOP\MyApplication.lnk" "$INSTDIR\MyApplication.exe" "" "$INSTDIR\MyApplication.exe" 0
- SectionEnd
- ;--------------------------------
- ;Installer Functions
- Function .onInit
- !insertmacro MULTIUSER_INIT
- !insertmacro MUI_LANGDLL_DISPLAY
- FunctionEnd
- ;--------------------------------
- ;Descriptions
- LicenseLangString license ${LANG_ENGLISH} license.rtf
- LicenseLangString license ${LANG_GERMAN} license_de.rtf
- LangString startmenu ${LANG_ENGLISH} "Add to Start Menu"
- LangString startmenu ${LANG_GERMAN} "Eintrag ins Startmenü"
- LangString DESC_Startmenu ${LANG_ENGLISH} "Add an Entry to the Start Menu"
- LangString DESC_Startmenu ${LANG_GERMAN} "Einen Eintrag ins Startmenü hinzufügen"
- LangString desktop ${LANG_ENGLISH} "Add a Desktop Icon"
- LangString desktop ${LANG_GERMAN} "Zum Desktop hinzufügen"
- LangString DESC_Desktop ${LANG_ENGLISH} "Add an Icon to the Desktop"
- LangString DESC_Desktop ${LANG_GERMAN} "Einen Eintrag zum Desktop hinzufügen"
- !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
- !insertmacro MUI_DESCRIPTION_TEXT ${Startmenu} $(DESC_Startmenu)
- !insertmacro MUI_DESCRIPTION_TEXT ${Desktop} $(DESC_Desktop)
- !insertmacro MUI_FUNCTION_DESCRIPTION_END
- ;--------------------------------
- ;Uninstaller Section
- Section "Uninstall"
- DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLATIONNAME}"
- DeleteRegKey SHCTX "Software\${INSTALLATIONNAME}"
- Delete $INSTDIR\uninstall.exe
- Delete $INSTDIR\MyApplication.exe
- Delete $INSTDIR\*.qm
- Delete $INSTDIR\license*.rtf
- Delete $INSTDIR\mingwm10.dll
- Delete $INSTDIR\libgcc_s_dw2-1.dll
- Delete $INSTDIR\QtCore4.dll
- Delete $INSTDIR\QtGui4.dll
- RMDir $INSTDIR
- Delete "$SMPROGRAMS\${INSTALLATIONNAME}\Uninstall.lnk"
- Delete "$SMPROGRAMS\${INSTALLATIONNAME}\MyApplication.lnk"
- Delete "$DESKTOP\MyApplication.lnk"
- RMDir "$SMPROGRAMS\${INSTALLATIONNAME}"
- SectionEnd
- ;--------------------------------
- ;Uninstaller Functions
- Function un.onInit
- !insertmacro MULTIUSER_UNINIT
- !insertmacro MUI_UNGETLANGUAGE
- FunctionEnd
Das Skript liegt, wie die anderen Windows-spezifischen Dateien, im Verzeichnis win.
Die wichtigsten Einstellungen befinden sich gleich am Anfang: Die Variable QT definiert den Ort, an dem sich die Qt-Binärdaten befinden (Qt Creator und Co.). Von dort muss der Installer einige DLLs kopieren (s.u.).
Wir verwenden die NSIS-Skin „Modern UI”, die wesentlich schöner ist als das Standardaussehen des Installers. Im Win-Verzeichnis müssen daher 4 Bitmap-Dateien liegen, die in Zeile 35–38 definiert wurden. Dabei handelt es sich um Grafiken für den Installer. Die Header sind dabei 150x57 Pixel groß, die Wizard-Bilder 164x314px. Die Bild er sind optional. NSIS verwendet Standardbilder, falls keine angegeben wurden.
In Zeile 26–29 bestimmen wir, dass die Installation ggf. mit Superuser-Rechten ausgeführt werden muss. Das ist bei neueren Windows-Versionen (Vista, Windows 7) zwingend notwendig, wenn man Dateien in die Programmverzeichnisse kopieren will.
Zeilen 62–73 definieren den Installations- bzw. Deinstallationsdialog. Auch hier kann man bei Bedarf die Reihenfolge ändern oder bestimmte Punkte weglassen (z.B. Lizenzvereinbarung).
Interessant wird es in der Standardsektion des Installers (ab Zeile 93): Hier wird festgelegt, welche Dateien installiert werden, bzw. welche Dateien im Installer integriert werden. Für Qt-Programme sind folgende Dateien notwendig:
- exe-Datei aus dem Release-Verzeichnis
- mögliche Sprachdateien für Qt (Endung qm)
- Ressourcen für das Programm sowie den Installer (im Beispiel z.B. die Lizenztexte im RTF-Format)
- QT-DLLs – Essentiell, da das Programm sonst nicht ausführbar ist! Die im Beispiel gezeigten sind die Bibliotheken, die auf jeden Fall integriert werden müssen, wenn man den Qt-Creator und GCC als Compiler verwendet (deshalb die mingwm-DLL). Wird mit dem Compiler von Visual Studio gearbeitet, muss eine andere DLL eingebunden werden (steht in der Qt-Anleitung für Windows). Verwendet man weitere Qt-Module (z.B. Webkit oder Netzwerkklassen), müssen die dazugehörigen DLL-Dateien auch eingebunden werden.
- Registry-Einträge für den Uninstaller
- ggf. Einträge ins Startmenü und/oder auf den Desktop
Damit sind die wesentlichen Schritte getätigt. Wesentlich ist, dass die richtigen DLLs ausgewählt und im Installer verpackt werden. Nur so kann ein Qt-Programm ausgeführt werden – dies bedeutet aber auch gleichzeitig, dass die Größe der installierten Daten gewaltig wächst! QtCore4.dll und QtGui4.dll haben eine Größe von zusammen etwa 6 MB.
Beim Deinstallieren müssen natürlich alle Dateien gelöscht werden.
Weitere Teile des Qt-Tutorials:
- Teil 1: Qt-Projektdatei für mehrere Betriebssysteme (Windows/Mac/Linux) einrichten
- Teil 2: Übersetzungen in der main-Funktion in verschiedenen Betriebssystemen (Windows/Mac/Linux) laden
- Teil 3: Ressourcen unter mehreren Betriebssystemen (Windows/Mac/Linux) laden
- Teil 4: Kompilieren und Installation von Software unter Windows
- 0 Kommentare