Feb 09 2009
NSIS installer for a Ruby application – Part 2 – Install Ruby and a gem
In Part 1 of this series we had a look at the general structure of a NSIS script as it was created for us by the HM NIS editor and IDE. We previously defined three components to be installed by our installer:
- Ruby (the target machine that our application is installed on requires Ruby)
- MyGem (our application is dependent on this fictitious gem)
- MyApplication (this is our application to be installed)
In this part we will look at how we will let the installer take care of the Ruby and MyGem components.
To start off, place the following at the top of your code:
!include LogicLib.nsh
This includes the LogicLib library and allow us to write more readable code by providing us some macros to write traditional logical structures for example IF and CASE structures
Ruby
Our application needs Ruby to be installed on the target machine. In the case that Ruby is not installed on the machine we want to relieve the user from having to install Ruby separately. Instead we want to install it for him.
In the example in Part one we replace the code:
Section "Ruby" SEC01 SectionEnd
with (we will go through this in detail):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | Section "ruby" SEC01 ; read the registry to check if there is not already a local installation of ruby readRegStr $0 HKLM "SOFTWARE\RubyInstaller" Path ${If} $0 != '' ; ruby installed MessageBox MB_OK 'Ruby is already installed on the system. The automated installation of Ruby will not proceed' ${Else} ; no ruby installer MessageBox MB_OK 'The ruby installer will now be downloaded and executed. This might take a few moments.' ; download and install ruby NSISdl::download /NOIEPROXY "http://rubyforge.org/frs/download.php/29263/ruby186-26.exe" "ruby186-26.exe" Pop $R0 ${If} $R0 == 'success' ; ruby download successful StrCpy $0 '' ; rum the one click installer ExecWait '"ruby186-26.exe"' $0 ${If} $0 == '' ; execution of one click installer failed MessageBox MB_OK "Ruby install failed. Please install Ruby manually" ${EndIf} ; delete the ruby one click installer ${Else} ; ruby download not successfull MessageBox MB_OK "Ruby download failed. Please download and install Ruby manually" ${EndIf} Delete "ruby186-26.exe" ${EndIf} SectionEnd |
Lets go through the code in detail
- We make the assumption that if Ruby is installed on the system that there will be a registry entry for the installation. We check for this registry entry with the readRegStr command (line 3).
- If we find an entry in the registry we prompt (MessageBox) this to the user and we do not proceed with the Ruby installation (line 6).
- If Ruby is not installed we notify the user that the installer will download the Ruby one-click installer and then proceed with the download (NSISdl::download, line 11)
- A successful download will place the success string on the stack. We Pop the top value from the stack and store in $0 (line 12).
- The installer inspects $0 and is the download was successful it proceeds to running the Ruby one-click installer (ExecWait, line 17)
- The return value of the one-click installer is inspected to determine a successful install. In the case of failure this is prompted to the user (lines 18-20).
- Towards the end of the script we handle the case of a failed download (lines 23-25).
- Finally the installer deletes the downloaded one-click installer (Delete, line 27)
MyGem
The installer needs to take care of the installation of our required gem, MyGem. To minimize the insteraction between the user and the installation process the installer installs the gem from a file in the installation package. This file contains the gem for local install.
Once again refering to the example in Part 1 one, we replace the code:
Section "MyGem" SEC02 SectionEnd
with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Section "MyGem" SEC02 SetOutPath "$INSTDIR\client" File "my_gem-x86-mswin32-60.gem" # check if ruby is installed and install the mygem gem locally if so readRegStr $0 HKLM "SOFTWARE\RubyInstaller" Path ${If} $0 != '' ; ruby installed StrCpy $1 '' ; install the mygem locally ExecWait '"$0\bin\gem.bat" install my_gem-x86-mswin32-60.gem' $1 ${If} $1 == '' MessageBox MB_OK "Gem install failed. Please install the MyGem gem manually" ${EndIf} ${Else} ; ruby not installed MessageBox MB_OK "Ruby is not installed. Please install ruby and then run the installer again or install the MyGem gem manually" ${EndIf} Delete "my_gem-x86-mswin32-60.gem" SectionEnd |
By now you should be able to follow the code quite easily. I will just highlight to things:
- Yet again we have to check if Ruby is installed on the target machine (line 5).
- Note that you have to give the full path to the gem batch file when triggering the gem installation (line 10).
Choosing Components
You might what to give you users the option to choose the components that they want to install. The modern user interface makes it really easy for you.
Add the following to your script below !insertmacro MUI_PAGE_COMPONENTS:
!insertmacro MUI_PAGE_COMPONENTS
And at the end of all your section code add:
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Installs ruby. The installer will download the ruby one click installer and execute. Alternatively you can install ruby manually." !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Installs the MyGem gem. The gem requires ruby to be installed." !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "Installs the MyApplication." !insertmacro MUI_FUNCTION_DESCRIPTION_END
I am going to leave it at that. In Part 3 we will look at you can make certain components compulsory, how we can write our script so that we can also use it for future releases of MyApplication and a few extra tips and tricks to clean up the script.
Happy coding!
Popularity: 12% [?]
Comments Off
