I have been using Visual Studio’s ‘Setup Project’ template for creating Windows installers to install my applications on a Windows computer. It’s pretty straight forward and easy, but gets a bit complicated when we need to do something more advanced. I knew there were things like InstallShield but they cost money.
Recently I was introduced to a new tool named as Nullsoft Scriptable Install System (NSIS). It’s completely free, and is a professional open source system to create Windows installers. It is driven by scripts (using a custom language) and offers a myriad of built-in features and functions covering all the basic installer necessities, from layout of install wizard dialogs, to manipulating files and registry keys.
Installing NSIS is very easy. Go to its home page at http://nsis.sourceforge.net and download the latest version. I used 2.43.
There are two types of installers that can be created using NSIS. The simple one is based on zip file. You package all your files into a single zip file and then feed it to the NSIS (Main Menu > Compiler > Installer based on ZIP file).
It will generate a setup exe which the end user can execute to copy your files into a specified directory.
The next option is the more powerful and flexible one. You create a NSIS script file (which is just a text file with extension as .nsi) with all the details of the installer like how many navigation pages it should have, what files need to be copied, and what values to be added to registry, etc. All these are specified through NSIS's own script language which is fairly easy to learn.
Once the script is ready and all the required files mentioned in the script are placed at the proper folders, you can right click on the script file and choose 'Compile NSIS Script' option. NSIS will then compile this script and will create a single setup exe file.
Now let us see the internals of such a script file. In this example, I am creating a Windows installer for my free software tool SQL Analyzer.
[Remember to get a fine text editing tool such as Notepad++ which has line number support and syntax highlighting for NSIS].
Initially I am defining some constants using the !define keyword. These are some string constants that will be used later on.
!define PRODUCT_NAME "SQL Analyzer" !define PRODUCT_VERSION_MAJOR 7 !define PRODUCT_VERSION_MINOR 0 !define PRODUCT_DISPLAY_VERSION "7.0" !define PRODUCT_PUBLISHER "Coolwayfarer" !define PRODUCT_WEB_SITE "http://www.codeplex.com/sqlanalyzer" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" ; !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_INSTALL_DIR "$PROGRAMFILES\SQL Analyzer"
Anything that comes after a $ sign is a predefined constant or variable. For example $PROGRAMFILES will translate into the user’s program files folder (typically C:\Program Files\).
Next we need to specify what compression technique we are using and what kind of user interface is required for the installer.
SetCompressor /SOLID lzma
!include "MUI2.nsh"
Here I am using the lzma. Don’t worry about that, it gives maximum compression. I also include a header file (you don’t need to get a copy of that file to include it) for the settings for Modern UI 2 (MUI2) which is the latest version of a user interface in a wizard style.
Next, the settings for the installer interface are specified.
!define MUI_ABORTWARNING !define MUI_ICON "resources\sqlanalyzer.ico" !define MUI_UNICON "resources\sqlanalyzer.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP "resources\sqlanalyzerheader.bmp" !define MUI_HEADERIMAGE_RIGHT !define MUI_HEADER_TRANSPARENT_TEXT !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\sqlanalyzerwelcome.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH
As you can see, things like MUI_ICON are predefined properties/settings. Here I have specified an icon for the installer and two images, one for the header and another one for the welcome page. Note that the files are put in a relative path to the script file.
Now the different wizard pages in the installer are specified.
; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !define MUI_LICENSEPAGE_CHECKBOX !insertmacro MUI_PAGE_LICENSE "resources\license.txt" ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" !define MUI_FINISHPAGE_NOREBOOTSUPPORT !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English"
Anything that starts with a semicolon is a comment. So I have pages like Welcome page, license page, etc. defined here. Note that in the finish page, I have an option specified to show readme file and it points to the file README.txt in the installed location ($INSTALLDIR). We will see in a moment that as part of our installation, we are copying this file as well.
Now we specify some basic settings for the installer itself.
Name "${PRODUCT_NAME}" OutFile "${PRODUCT_NAME} Setup.exe" InstallDir "${PRODUCT_INSTALL_DIR}" ShowInstDetails show ShowUnInstDetails show BrandingText "${PRODUCT_PUBLISHER}" RequestExecutionLevel admin
We are making use of the constants we defined earlier here to specify things like the installer file (OutFile: which will be now ‘SQL Analyzer Setup.exe’).
Now the settings are complete and we need to define the actions during the installation. This is done by defining a section with some name.
Section "MainSection" MainSection
;Action goes here...
SectionEnd
Within this section, first we need to set the out path (which is the installation directory) and then copy all the required files to this path.
SetOutPath "$INSTDIR" SetOverwrite ifnewer ;Copy files File "/oname=sqlanalyzer.ico" "resources\sqlanalyzer.ico" ;Binary of the application. File "/oname=SQLAnalyzer.exe" "files\SQLAnalyzer.exe" ;Binary of the application. File "/oname=sqlanalyzer.gif" "files\sqlanalyzer.gif" ;A sample screen shot. File "/oname=README.txt" "files\README.txt" ;Readme file. File "/oname=RICHTX32.OCX" "files\RICHTX32.OCX" ;Required OCX control: Rich Text Box. File "/oname=COMDLG32.OCX" "files\COMDLG32.OCX" ;Required OCX control: Common Dialog. File "/oname=MSFLXGRD.OCX" "files\MSFLXGRD.OCX" ;Required OCX control: Flex Grid.
Next, I am registering the dependent OCX controls and creating Start Menu shortcuts.
;Register the OCX controls. Exec 'regsvr32 "$INSTDIR\RICHTX32.OCX" /S' Exec 'regsvr32 "$INSTDIR\COMDLG32.OCX" /S' Exec 'regsvr32 "$INSTDIR\MSFLXGRD.OCX" /S' ;Create Start Menu folders and shortcuts. CreateDirectory "$STARTMENU\Programs\${PRODUCT_NAME}" CreateShortCut "$STARTMENU\Programs\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\SQLAnalyzer.exe" CreateShortCut "$STARTMENU\Programs\${PRODUCT_NAME}\README.lnk" "$INSTDIR\README.txt" CreateShortCut "$STARTMENU\Programs\${PRODUCT_NAME}\Sample.lnk" "$INSTDIR\sqlanalyzer.gif" CreateShortCut "$STARTMENU\Programs\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe"
Any external tool can be used using the Exec keyword. If you need to run your own custom tool as part of installation, first copy that tool and then use this command. NSIS can create an uninstaller automatically using the keyword WriteUninstaller.
If we need this product to appear on Windows installed programs list (Add/Remove Programs), then we need to write a registry entry as below.
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\sqlanalyzer.ico" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_DISPLAY_VERSION}" WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "VersionMajor" "${PRODUCT_VERSION_MAJOR}" WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "VersionMinor" "${PRODUCT_VERSION_MINOR}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
We are almost done and only thing left now is to instruct NSIS on what to do while the uninstaller is executed. Well, we need to remove whatever files we have copied, directories and shortcuts we have created, and registry entries we have made. This is specified in a section named Uninstall as below.
Section "Uninstall" ;Unregister the OCX controls. Exec 'regsvr32 -u "$INSTDIR\RICHTX32.OCX" /S' Exec 'regsvr32 -u "$INSTDIR\COMDLG32.OCX" /S' Exec 'regsvr32 -u "$INSTDIR\MSFLXGRD.OCX" /S' ;Delete all the files Delete "$INSTDIR\sqlanalyzer.ico" Delete "$INSTDIR\SQLAnalyzer.exe" Delete "$INSTDIR\sqlanalyzer.gif" Delete "$INSTDIR\README.txt" Delete "$INSTDIR\RICHTX32.OCX" Delete "$INSTDIR\COMDLG32.OCX" Delete "$INSTDIR\MSFLXGRD.OCX" Delete "$INSTDIR\Uninstall.exe" ;Remove the installation folder. RMDir "$INSTDIR" ;Remove the Shortcuts Delete "$STARTMENU\Programs\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" Delete "$STARTMENU\Programs\${PRODUCT_NAME}\README.lnk" Delete "$STARTMENU\Programs\${PRODUCT_NAME}\Sample.lnk" Delete "$STARTMENU\Programs\${PRODUCT_NAME}\Uninstall.lnk" RMDir /r "$STARTMENU\Programs\${PRODUCT_NAME}" ;Remove the entry from 'installed programs list' DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" SectionEnd
That’s it! Now make sure that the extension of this script file is .nsi (download the complete file from here). Right click on this file from Windows Explorer and you will see an option ‘Compile NSIS Script’ if you have successfully installed NSIS.
If there is any error, the compiler will inform about it specifying the line number in the script. So it is easy to fix issues. If everything went fine, the installer exe will be created at the same location.
Now let us see how the installer interface looks like with the settings in the script file.
This is the first welcome screen. The image on the left is the onwe we specified with ‘sqlanalyzerwelcome.bmp’.
Here in the second page the license from a text file is displayed. The ‘Install’ button will be enabled only when ‘I accept…’ checkbox is checked.
This screen shows the progress of the installation.
This is the final page with an option to show Readme file. After the installation, the Start Menu shortcuts are created as below.
The product will also be listed under ‘Add/Remove Programs’
Now on clicking the Uninstall button, the uninstaller will get executed and will remove all the changes we have done.
You can download all the files and the script as a zip from here or just try out the installer from here. Let me know if this article helped you and feel free to post any questions you may have. Remember to first check out the tutorial and documentation on NSIS site which is very detailed.
Hi Recently I was assigned to create a installer for a project which is of 971MB,which contains lots of data like jpgs,img,dlls,and EXE's.how can i make an installer by addding all these things..can u guide me ...
ReplyDeleteany help will be greatly appreciated...
You can use this:
ReplyDeleteFile /r "PathToFoldeWithFiles\*.*"
Great information with screenshots.
ReplyDeleteHow can we overwrite system DLLs or executable during the installation? Let's say my application uses the same dll (newer versio) which is being used by Windows and I want to replace the currnt one with mine. This might also require moving the DLL(s) from the installed directory to system32 or any other location.
Thanks
Thanks Rowshan.
ReplyDeleteI am not sure how to deal with this situation.
Sameer,
ReplyDeleteActually I partially found the answer to my questions. Here is how you can handle the DLLs:
http://nsis.sourceforge.net/Docs/AppendixB.html
You might also use "SetOverwrite ifnewer" in the section part.
However, I haven't found a way to move files to another directory during or after the installation.
I also found how to copy a file to another directory using CopyFiles command. The file can also be deleted by using Delete command.
ReplyDeleteThaks Rowshan. Yeah, moving is normally achieved by copying and deleting.
ReplyDeleteHi, I've created an installer with my apps. Now I want to leave it to the user to decide which apps they want to execute/unpack. I need to know how to remove all files and register settings. Is the a quick way to do this? As I do not know which app they ran, What I really need to do is take a snap shot of the registry, before any apps are installed, then take another snap shot when they are finished, I need a way to get this difference and automate the removal.
ReplyDeleteI'm not sure on this. Try posting your questions on http://stackoverflow.com
ReplyDeleteThis is an Amazing article. U explained everything in such a simple and great way.Thanks!!
ReplyDeleteYou are most welcome, Megha. Glad to know that it was useful.
ReplyDelete