Feb 02 2009
NSIS installer for a Ruby application – Part 1 – HM NIS wizard output
I am working on an NSIS (Nullsoft Scriptable Install System) installer for a Ruby application (Dradis – check it out!). In this series I will try to keep log of how I progress with this.
I am using HM NIS editor and IDE for NSIS to make the task a little easier. To get out of the blocks a little quicker I used the HM NIS wizard to create a simple framework from where I will progress.
The wizard allows you to install different components (groups). These are typically different parts of your application and dependencies that needs to be installed. I created the following components:
- Ruby (this will download and install the Ruby one-click installer if ruby is not installed)
- MyGem (this will install the the required gems)
- MyApplication (this will install my application)
The wizard also lets you pick a GUI type. I picked modern. You can choose between modern, classic or none.
The script generated by the wizard will look something like the following (do not bother to read it all right now, I will go into detail for some parts of it):
; Script generated by the HM NIS Edit Script Wizard. ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "My application" !define PRODUCT_VERSION "1.0" !define PRODUCT_PUBLISHER "My company, Inc." !define PRODUCT_WEB_SITE "http://www.mycompany.com" !define PRODUCT_UNINST_KEY "SoftwareMicrosoftWindowsCurrentVersionUninstall${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" ; MUI 1.67 compatible ------ !include "MUI.nsh" ; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}ContribGraphicsIconsmodern-install.ico" !define MUI_UNICON "${NSISDIR}ContribGraphicsIconsmodern-uninstall.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !insertmacro MUI_PAGE_LICENSE "c:pathtolicenceYourSoftwareLicence.txt" ; Directory page !insertmacro MUI_PAGE_DIRECTORY ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "Setup.exe" InstallDir "$PROGRAMFILESMy application" ShowInstDetails show ShowUnInstDetails show Section "Ruby" SEC01 SectionEnd Section "MyGem" SEC02 SectionEnd Section "MyApplication" SEC03 SectionEnd Section -AdditionalIcons SetOutPath $INSTDIR WriteIniStr "$INSTDIR${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateDirectory "$SMPROGRAMSMy application" CreateShortCut "$SMPROGRAMSMy applicationWebsite.lnk" "$INSTDIR${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMSMy applicationUninstall.lnk" "$INSTDIRuninst.exe" SectionEnd Section -Post WriteUninstaller "$INSTDIRuninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIRuninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." FunctionEnd Function un.onInit MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 Abort FunctionEnd Section Uninstall Delete "$INSTDIR${PRODUCT_NAME}.url" Delete "$INSTDIRuninst.exe" Delete "$SMPROGRAMSMy applicationUninstall.lnk" Delete "$SMPROGRAMSMy applicationWebsite.lnk" RMDir "$SMPROGRAMSMy application" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" SetAutoClose true SectionEnd
The first thing to get you head around here is the general layout of a NSIS script and how this maps to the final installer. For a thorough read on this refer to section 2.3 Scripting structure in the NSIS User Manual. As a brief overview:
- Compiler commands
The instructions that start with ! (exclamation mark) are compiler commands. These commands are executed on compile time. - Installer attributes
Close to the top of your script you will note a few installer attributes that are defined. For example:Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "Setup.exe" InstallDir "$PROGRAMFILESMy application"
These attributes are used and referenced later in the installation process
- Installer pages
A non silent installer consist of different pages. These pages will mostly be taken care of by the GUI interface that you picked. The predefined GUI pages that are used are specified by the !insertmacro directives. For example:!insertmacro MUI_PAGE_WELCOME
specifies that the modern GUI’s welcome page should be inserted.
- Sections
You will note that chunks of the script are wrapped by the Section and SectionEnd directives. These mostly correspond to different components of your application to be installed.
In my example you will note sections for Ruby, MyGem and MyApplication. You will also notice some sections that start with un. These sections are called during uninstall.
The code inside a section are executed on the machine that the installer is being run on. Sections are executed in the order as they appear in the code. - Functions
Functions are pieces of script code that are called either from within sections by using Call functionName or they are called at different points in the script execution as Callback functions. For example .onInit will be called when the installer is initiated.
When you defined your application’s different components in the wizard you were allowed to specify the different files that should be installed. These files are referenced in the install and uninstall sections. In the install sections you will note something similar to:
SetOutPath "$INSTDIRmy_folder" File "application_filesmyapplication.rb"
The first line specifies that what follows after that line (File “application_files\myapplication.rb”) should be applied to the $INSTDIR\my_folder directory. It effectively changes the current directory path. The second line instructs the installer to copy the file located at application_files\myapplication.rb to the current path.
In the uninstall section you will note code that is similar to:
Delete "$INSTDIRmy_foldermyapplication.rb" RMDir "$INSTDIRmy_folder"
It instructs the uninstaller to delete the file at $INSTDIR\my_folder\myapplication.rb and remove the folder $INSTDIR\my_folder.
I am going to leave it at that. In the next post I’ll describe how I install Ruby and the required gem on running the installer.
Popularity: 14% [?]

February 9th, 2009 at 12:53 pm
[...] this part of the series (see Part 1 and Part 2) we [...]
March 1st, 2009 at 8:33 pm
[...] Please note that I have written an updated version of this post that can be found here [...]