Embedding other installers

From NSIS Wiki

Oftentimes one runs an installer that contains installers for other programs. For example, I wrote an application for a client that has a pocket PC component. The installer I wrote for them also installs Active Sync, the .NET CF Version 2 redistributable, and ntbackup being many of the machines run XP home edition. This page demonstrates how to do this.


A simple example

Rather than lecture theory first, let's jump right in with an example snippet. This demonstrates 2 techniques, prompting the user for permission and checking for the existence of a file to determine whether to install an msi.

; These are the programs that are needed by ACME Suite.
Section -Prerequisites
  SetOutPath $INSTDIR\Prerequisites
  MessageBox MB_YESNO "Install Microsoft ActiveSync?" /SD IDYES IDNO endActiveSync
    File "..\Prerequisites\ActiveSyncSetup.exe"
    ExecWait "$INSTDIR\Prerequisites\ActiveSyncSetup.exe"
    Goto endActiveSync
  MessageBox MB_YESNO "Install the Microsoft .NET Compact Framework 2.0 Redistributable?" /SD IDYES IDNO endNetCF
    File "..\Prerequisites\NETCFSetupv2.msi"
    ExecWait '"msiexec" /i "$INSTDIR\Prerequisites\NETCFSetupv2.msi"'
    IfFileExists $SYSDIR\ntbackup.exe endNtBackup beginNtBackup
    Goto endNtBackup
    MessageBox MB_OK "Your system does not appear to have ntbackup installed.$\n$\nPress OK to install it."
    File "..\Prerequisites\ntbackup.msi"
    ExecWait '"msiexec" /i "$INSTDIR\Prerequisites\ntbackup.msi"'

Now for theory

The process is simple. Copy the file over and execute it. Use ExecWait to pause your installer until the embedded installer is finished. In theory you could capture the return value of the installer and react to it. I've yet to explore this avenue. In the example above the installers were MSI's and not exes so I have to execute the installers with msiexec /i <installer.msi>.

Using the return value from the ExecWait

This is the bit of code I have been using for installing dotnet 2 where needed. I'll skip over the Check function (it will return 1 if it is installed). I needed IfErrors before the ExecWait to clear the error flag. The IfErrors after the ExecWait will return true if the execution returned an error (usually meaning an exitcode != 0 or for example if the user aborted the dotnet installer). In that case it will jump to the appropriate label and Abort. If everything is OK, it will delete the dotnet installer and continue.

	Call CheckFrameWork
	Pop $0
	${if} $0 != "1"
		IfErrors continue
		File "dotnetfx.exe"
		ExecWait '"$INSTDIR\dotnetfx.exe"'
		IfErrors error_installing_dotnet
	Delete $INSTDIR\dotnetfx.exe
	goto done
	Delete $INSTDIR\dotnetfx.exe

A more complex example

This is a real world example. I use this to install several programs on computers for a client of mine. I then install the Application I wrote for the client using a NSIS script. You will need to download several binaries to get this script to compile.

; Script generated by the HM NIS Edit Script Wizard.
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "App Deploy"
!define PRODUCT_VERSION "1.0"
!define PRODUCT_PUBLISHER "ZippySoft"
SetCompressor lzma
!include "UserManagement.nsh"
; MUI 1.67 compatible ------
!include "MUI.nsh"
; MUI Settings
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
; Welcome page
!insertmacro MUI_PAGE_WELCOME
; Components page
; Instfiles page
; Finish page
!insertmacro MUI_PAGE_FINISH
; Language files
!insertmacro MUI_LANGUAGE "English"
; Reserve files
; MUI end ------
OutFile "AppDeploy.exe"
InstallDir "$PROGRAMFILES\App Deploy"
ShowInstDetails show
  SetOutPath "$INSTDIR"
  SetOverwrite ifnewer
Section "Epson Stylus C88+" SEC01
  File "drivers\epson11896.exe"
  ExecWait "$INSTDIR\epson11896.exe"
Section "Polaroid PDC700" SEC02
  MessageBox MB_OK \
    "The TWAIN drivers for Polaroid PDC700 are about to be installed. The Polaroid installer \
     will ask you to reboot. Please say no to this reboot request. The AppDeploy installer will \
     prompt you after installing all the other applications."
  File "drivers\pdc700_twain_driver.exe"
  ExecWait "$INSTDIR\pdc700_twain_driver.exe"
  AccessControl::GrantOnFile "C:\WINDOWS\twain_32\PDC700" "(BU)" "GenericRead + GenericWrite"
  SetRebootFlag true
Section "FireFox" SEC03
  ; To upgrade this package http://www.frontmotion.com/Firefox/fmfirefox.htm
  File "firefox\FMFirefoxCE-2.0-en-US.msi"
  ExecWait 'msiexec /i "$INSTDIR\Firefox Setup 2.0.exe" /passive '
Section "PDFCreator" SEC04
  File "PDFCreator\zPDFCreator-0_9_3-AD_DeploymentPackage-WithoutToolbar.msi"
  ExecWait '"msiexec" /i "$INSTDIR\zPDFCreator-0_9_3-AD_DeploymentPackage-WithoutToolbar.msi"  /passive'
Section "The GIMP" SEC05
  File "GIMP\gtk+-2.10.6-1-setup.exe"
  File "GIMP\gimp-2.2.13-i586-setup-1.exe"
  ExecWait '"gtk+-2.10.6-1-setup.exe"  /SP- /SILENT'
  ExecWait '"gimp-2.2.13-i586-setup-1.exe"  /SP- /SILENT'
Section "7Zip" SEC06
  File "7z442.msi"
  ExecWait '"msiexec" /i "$INSTDIR\7z422.msi"  /passive'
Section "PlaneDisaster.NET" SEC07
  File "PlaneDisaster.NET Setup.msi"
  ExecWait '"msiexec" /i "$INSTDIR\PlaneDisaster.NET Setup.msi"  /passive'
Section "Adobe Acrobat Reader 8" SEC08
  ; For information on Deploying acrobat reader 8 see http://www.appdeploy.com/packages/detail.asp?id=915
  File "AdbeRdr80_en_US.exe"
  ExecWait 'AdbeRdr80_en_US.exe /sPB /rs /l /msi"/qb-! /norestart /log c:\acrobat8.log ALLUSERS=2 EULA_ACCEPT=YES SUPPRESS_APP_LAUNCH=YES"'

External Links

Personal tools