Feb 02 2009

NSIS installer for a Ruby application – Part 1 – HM NIS wizard output

Category: Rails, Ruby, X Windowssiebert @ 7:52 pm

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% [?]

Share and Enjoy:
  • Digg
  • del.icio.us
  • Slashdot
  • Technorati

2 Responses to “NSIS installer for a Ruby application – Part 1 – HM NIS wizard output”

  1. usefulfor.com/ruby » NSIS installer for a Ruby application - Part 3 - A few script improvements says:

    [...] this part of the series (see Part 1 and Part 2) we [...]

  2. usefulfor.com/ruby » Ruby installer using NSIS (Part 1) says:

    [...] Please note that I have written an updated version of this post that can be found here [...]

Leave a Reply