NISRP Installer Script

From SpenchWiki
Jump to: navigation, search

NSIS Script

The installer used is the Nullsoft Scriptable Install System. I have posted this to help others who wish to learn how to write their own installers. The code below is the complete installer, which supports installing (files, registry, shortcuts), uninstalling, web links, executing custom programs and downloading installers from the internet, which cuts down the size of the compiled installer if it is an optional component (e.g. the C++/MFC run-time).

Code

/*
http://nsis.sourceforge.net/Creating_language_files_and_integrating_with_MUI

GetDLLVersion "MyApp.exe" $R0 $R1
IntOp $R2 $R0 >> 16
IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
IntOp $R4 $R1 >> 16
IntOp $R4 $R4 & 0x0000FFFF ; $R4 now contains release
IntOp $R5 $R1 & 0x0000FFFF ; $R5 now contains build
StrCpy $0 "$R2.$R3.$R4.$R5" ; $0 now contains string like "1.2.0.192"
*/
!include "MUI2.nsh"

!define /date TIMESTAMP "%Y-%m-%d-%H-%M-%S"

SetCompressor lzma
RequestExecutionLevel admin

!define MUI_ABORTWARNING
!define MUI_ABORTWARNING_CANCEL_DEFAULT

!define MUI_UNABORTWARNING
!define MUI_UNABORTWARNING_CANCEL_DEFAULT

!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"

#######################################

!define PRODUCT_NAME		"NISRP"
!define PRODUCT_VERSION		"1.0"
!define PRODUCT_PUBLISHER	"balint at the domain spench full-stop decimal-point dot net"

!define UNINSTALLER			"Uninstall NISRP.exe"
!define NISRP_WWW			"http://spench.net/r/NISRP"
!define NISRP_RUN_KEY_NAME	"NISRP iTunes Plugin"
!define NISRP_REG			"Software\Baz's Appz\NISRP"
!define NISRP_REG_UNINSTALL	"Software\Microsoft\Windows\CurrentVersion\Uninstall\NISRP"
!define NISRP_DLL			"gen_NISRP.dll"

#######################################

BrandingText "${PRODUCT_NAME} ${PRODUCT_VERSION} by ${PRODUCT_PUBLISHER}"
Name "NISRP"
OutFile "${PRODUCT_NAME}-${PRODUCT_VERSION}_Setup.exe"

InstallDir "$PROGRAMFILES\Winamp\Plugins"
InstallDirRegKey HKCU "${NISRP_REG}" "InstallationDir"
# FIXME: HKCU Software\Winamp [default]

ShowInstDetails show

DirText "If you have Winamp, select its Plugins directory.$\n$\nIf not (i.e. you have iTunes) then you may install to wherever you choose."
# If string was continued on new line using '\' then it would overwrite "Destination Folder" group control text

Var StartMenuFolder
#Var PluginsFolder

#Page Directory
#Page InstFiles

#######################################

	!define MUI_WELCOMEPAGE_TITLE "Installer for ${PRODUCT_NAME} ${PRODUCT_VERSION}"
	!define MUI_WELCOMEPAGE_TITLE_3LINES # Extra space for the title area
	!define MUI_WELCOMEPAGE_TEXT "NISRP is the Non-Instrusive Song Rating Plugin for Winamp and iTunes.$\n$\nPress Next to continue."
!insertmacro MUI_PAGE_WELCOME

!insertmacro MUI_PAGE_COMPONENTS

	#!define MUI_DIRECTORYPAGE_VARIABLE $PluginsFolder
!insertmacro MUI_PAGE_DIRECTORY

	!define MUI_STARTMENUPAGE_DEFAULTFOLDER "NISRP"
	!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKCU
	!define MUI_STARTMENUPAGE_REGISTRY_KEY "${NISRP_REG}"
	!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "ShortcutDir"
!insertmacro MUI_PAGE_STARTMENU NISRP_Shortcuts $StartMenuFolder

!insertmacro MUI_PAGE_INSTFILES

	!define MUI_FINISHPAGE_NOAUTOCLOSE	# ShowInstDetails
	
    !define MUI_FINISHPAGE_RUN
#	!define MUI_FINISHPAGE_RUN_NOTCHECKED
    !define MUI_FINISHPAGE_RUN_TEXT "Start NISRP iTunes plugin"
    !define MUI_FINISHPAGE_RUN_FUNCTION "Launch_iTunes"
	
	!define MUI_FINISHPAGE_SHOWREADME "${NISRP_WWW}"
#	!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
	!define MUI_FINISHPAGE_SHOWREADME_TEXT "Open instructions (recommended)"
#	!define MUI_FINISHPAGE_SHOWREADME_FUNCTION "Launch_WWW"

	!define MUI_FINISHPAGE_LINK "NISRP Homepage"
	!define MUI_FINISHPAGE_LINK_LOCATION "${NISRP_WWW}"
	
	!define MUI_FINISHPAGE_NOREBOOTSUPPORT	# Saves some space
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

	!define MUI_UNFINISHPAGE_NOAUTOCLOSE	# ShowUninstDetails
!insertmacro MUI_UNPAGE_FINISH

!insertmacro MUI_LANGUAGE "English"

ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"

#######################################

VIProductVersion "1.0.0.0"

VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "NISRP"
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "1.0.0.0"
VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "The Non-Instrusive Song Rating Plugin"
VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "spench.net"
#VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "Test Application is a trademark of Fake company"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© Balint Seeber 2009. All rights reserved."
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "NISRP"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "1.0"
VIAddVersionKey /LANG=${LANG_ENGLISH} "InternalName" "${TIMESTAMP}"
#VIAddVersionKey /LANG=${LANG_ENGLISH} "OriginalFilename" ""
#VIAddVersionKey /LANG=${LANG_ENGLISH} "PrivateBuild" ""
VIAddVersionKey /LANG=${LANG_ENGLISH} "SpecialBuild" "Beta"

#######################################

Function .onInit
#	!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd

Section "!NISRP" secNISRP
	#SetShellVarContext all

	# call userInfo plugin to get user info.  The plugin puts the result in the stack
    #userInfo::getAccountType
    # pop the result from the stack into $0
    #pop $0
    # compare the result with the string "Admin" to see if the user is admin.
    # If match, jump 3 lines down.
    #strCmp $0 "Admin" +3

	SetOutPath $INSTDIR

	# Create backup if already exists
	#Rename "$INSTDIR" "$INSTDIR.${PRODUCT_VERSION}.${TIMESTAMP}"
	
	File /oname=${NISRP_DLL} Release\NISRP.dll
	
	WriteRegStr HKCU "${NISRP_REG}" "InstallationDir" "$INSTDIR"

	# define uninstaller name
	writeUninstaller "$INSTDIR\${UNINSTALLER}"
	
	!insertmacro MUI_STARTMENU_WRITE_BEGIN NISRP_Shortcuts
		CreateDirectory	"$SMPROGRAMS\$StartMenuFolder"
		CreateShortCut	"$SMPROGRAMS\$StartMenuFolder\Start iTunes plugin.lnk" "rundll32.exe" "$\"$INSTDIR\${NISRP_DLL}$\",iTunes" "" "" "" "" "Start the NISRP plugin for iTunes (it will wait in the background for iTunes)"
		CreateShortCut	"$SMPROGRAMS\$StartMenuFolder\Stop iTunes plugin.lnk" "rundll32.exe" "$\"$INSTDIR\${NISRP_DLL}$\",Quit iTunes" "" "" "" "" "Stop the NISRP plugin for iTunes (it will no longer appear when running iTunes)"
		CreateShortCut	"$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\${UNINSTALLER}"
	!insertmacro MUI_STARTMENU_WRITE_END

	WriteRegStr		HKLM "${NISRP_REG_UNINSTALL}" "DisplayName" "NISRP"
	WriteRegStr		HKLM "${NISRP_REG_UNINSTALL}" "UninstallString" "$\"$INSTDIR\${UNINSTALLER}$\""
	WriteRegStr		HKLM "${NISRP_REG_UNINSTALL}" "Publisher" "spench.net"
	WriteRegStr		HKLM "${NISRP_REG_UNINSTALL}" "URLInfoAbout" "http://spench.net/r/NISRP"
	WriteRegDWORD	HKLM "${NISRP_REG_UNINSTALL}" "NoModify" 1
	WriteRegDWORD	HKLM "${NISRP_REG_UNINSTALL}" "NoRepair" 1
	WriteRegStr		HKLM "${NISRP_REG_UNINSTALL}" "DisplayIcon" "$\"$INSTDIR\${UNINSTALLER}$\""
	
	# FIXME: Typelib
	# iTunes.exe /regserver
SectionEnd

LangString desc_secNISRP ${LANG_ENGLISH} "The Non-Instrusive Song Rating Plugin"

Section "Autorun iTunes plugin" secAutorun_iTunes
	WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${NISRP_RUN_KEY_NAME}" "rundll32.exe $\"$INSTDIR\${NISRP_DLL}$\",iTunes"
SectionEnd

LangString desc_secAutorun_iTunes ${LANG_ENGLISH} "Automatically start NISRP when you log on so it works seamlessly with iTunes (otherwise you will have to start it manually)"

!define DOWNLOAD_LOCATION	"$INSTDIR\Downloaded"
!define RUNTIME_FILE		"${DOWNLOAD_LOCATION}\vcredist_x86_2008_sp1.exe"

# FIXME: Check if it's already installed
# HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Winners\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_none_ea33c8f0b247cd77\9.0
Section "VC++ 2008 SP1 Runtime" secRuntime	# Was '/o' but perhaps better to leave it on by default (those in the know will uncheck it)
	AddSize 4119
	# Download is placed in installation directory
	SetOutPath ${DOWNLOAD_LOCATION}
	NSISdl::download "http://download.microsoft.com/download/d/d/9/dd9a82d0-52ef-40db-8dab-795376989c03/vcredist_x86.exe" "${RUNTIME_FILE}"
		Pop $R0 ;Get the return value
		StrCmp $R0 "success" install
			MessageBox MB_YESNO|MB_ICONEXCLAMATION "Download failed: $R0$\n$\n${PRODUCT_NAME} may not run until this component is correctly installed.$\n$\nDo you wish to continue?" IDYES true IDNO false
			true:
				Goto finish
			false:
				Abort "Download failed: $R0"
install:
	# FIXME: Silent install?
	ExecWait "${RUNTIME_FILE}"
finish:
	#ExecShell "open" "http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en"
	#MessageBox MB_OK|MB_ICONINFORMATION "The Microsoft download site has been opened.$\n$\nPlease click OK once you have installed the runtime."
SectionEnd

LangString desc_secRuntime ${LANG_ENGLISH} "Runtime for C++ and MFC 9.0 SP1 (will be downloaded from Microsoft)"

!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  !insertmacro MUI_DESCRIPTION_TEXT ${secNISRP} $(desc_secNISRP)
  !insertmacro MUI_DESCRIPTION_TEXT ${secRuntime} $(desc_secRuntime)
  !insertmacro MUI_DESCRIPTION_TEXT ${secAutorun_iTunes} $(desc_secAutorun_iTunes)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

#Function Launch_WWW
#	ExecShell "open" "${NISRP_WWW}"
#FunctionEnd

Function Launch_iTunes
	# Single quote ' not used since args are not passed properly (however won't work on Win98?)
	Exec "rundll32.exe $\"$INSTDIR\${NISRP_DLL}$\",iTunes"
FunctionEnd

#######################################

#Page uninstConfirm	# Cannot use this as it appears in the installer too

Function un.onInit
#	!insertmacro MUI_UNGETLANGUAGE
FunctionEnd

# create a section to define what the uninstaller does.
# the section will always be named "Uninstall"
Section "Uninstall" secUninstall
	#SetShellVarContext all

	DetailPrint "Exiting iTunes plugin..."
	ExecWait "rundll32.exe $\"$INSTDIR\${NISRP_DLL}$\",Quit iTunes"
	# FIXME: Could check for mutex
	
	#DetailPrint "Sleeping for a moment..."
	#Sleep 1000
 
	# Always delete uninstaller first
	Delete "$INSTDIR\${UNINSTALLER}"
 
	# now delete installed file
	Delete "$INSTDIR\${NISRP_DLL}"
	
	IfFileExists "${DOWNLOAD_LOCATION}" 0 continue
		MessageBox MB_YESNO|MB_ICONQUESTION "Would you also like to delete the files the installer downloaded from:$\n$\n${DOWNLOAD_LOCATION}" IDYES true IDNO continue
true:
		RMDir /r "${DOWNLOAD_LOCATION}"
continue:
	RMDir "$INSTDIR"
	
	!insertmacro MUI_STARTMENU_GETFOLDER NISRP_Shortcuts $StartMenuFolder
	Delete	"$SMPROGRAMS\$StartMenuFolder\Start iTunes plugin.lnk"
	Delete	"$SMPROGRAMS\$StartMenuFolder\Stop iTunes plugin.lnk"
	Delete	"$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk"
	RMDir	"$SMPROGRAMS\$StartMenuFolder"	#/r
	
	DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "${NISRP_RUN_KEY_NAME}"

	DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NISRP"
	
	DeleteRegKey /ifempty HKCU "${NISRP_REG}"
SectionEnd