SetCompressor lzma RequestExecutionLevel admin !addPluginDir "." !AddIncludeDir "." ; I think this is automatic ;--------------------------------------------------------------------------------------- # Variables ;--------------------------------------------------------------------------------------- ; Each game should set these in its components section!!! Var GameName ; This is the "name" of the game, and it should be the directory name under which the game will live on disc, in the registry, everywhere. Keep it simple. Var GameExe ; The executable to launch to play Var GameMCExe ; The executable to launch when running from Media Center. May or may not be the same as $GameExe. Var GameMCArgs ; The arguments to pass to $GameMCExe so it knows how to behave. Typically either "-mce" (if the game is Media Center aware) or "$GameExe" if you're using a wrapper. ;-------------------------------------------------------------------------------------- ; These should not be messed with Var GameDir ; NOTE: This will be set for you as $INSTDIR\$GameName Var GameGUID ; NOTE: This will be set for you once the GUID is generated. Var GamePath ; NOTE: This will be set for you during uninstalling as the parent directory of the game's directory. We avoid using $INSTDIR because of re-installs to different directories. Var AppName ; NOTE: This is set automajically between installing and uninstalling so that the uninstaller isn't a multi-game uninstaller Var StartMenuFolder ; NOTE: Used to store the value for the start menu folder in the MUI macro /**************************************************************************/ ; Upsell Variables Var Dialog ; This parameter holds the custom dialog Var Label ; This parameter holds latest created label control Var Link ; This parameter holds the latest created link control Var RadioFull ; Handle to Full radio button Var RadioCustom ; Handle to Custom radio button Var CheckTB ; Handle to Toolbar checkbox radio button Var CheckSCH ; Handle to Chrome checkbox radio button Var CheckboxState ; checkbox state Var CMD ; commandline parameters for Upsell-silent-installer /***************************************************************************/ # Defines !define REGKEY "SOFTWARE\MyApp" !define VERSION 1.1.0.0 !define COMPANY company !define PUBLISHER company !define URL www.company.com !define WEBSITE http://www.company.com !define CSIDL_COMMONAPPDATA '0x23' !define VISTA_ONLY 0 /**************************************************************************/ ; Upsell Includes !include nsDialogs.nsh !include LogicLib.nsh ; Upsell MUI Settings Start ****** AddBrandingImage left width 498 ; Upsell MUI Setting End ****** /**************************************************************************/ # MUI defines !define MUI_ICON "MyAppicon.ico" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_LICENSEPAGE_CHECKBOX !define MUI_UNICON "${NSISDIR}\contrib\graphics\icons\modern-uninstall.ico" !define MUI_UNFINISHPAGE_NOAUTOCLOSE !define UMUI_LANGDLL_REGISTRY_ROOT HKLM !define UMUI_LANGDLL_REGISTRY_KEY "${REGKEY}" !define UMUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage # Included files !include Sections.nsh !include UMUI.nsh !include FileFunc.nsh !include WinVer.nsh !include XML.nsh # Declare macros from included headers !insertmacro un.GetParameters !insertmacro un.GetFileName # Reserved Files !insertmacro MUI_RESERVEFILE_LANGDLL ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" # Interface configuration Page custom CreateCustomPage CustomPageLeave ; Adding a custom page. !define UMUI_HEADERBGIMAGE_BMP "MY_header.bmp" !define UMUI_LEFTIMAGE_BMP "MyAppbanner.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH !define MUI_ABORTWARNING !define MUI_WELCOMEPAGE_TITLE_3LINES !define MUI_FINISHPAGE_TITLE_3LINES # Installer pages !define MUI_WELCOMEFINISHPAGE_CUSTOMFUNCTION_INIT onWelcomePage !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "EULA.txt" ;!insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "SOFTWARE\MyApp\MyApp" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !define MUI_STARTMENUPAGE_DEFAULTFOLDER "company\MyApp" !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfVista !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH # Installer languages !insertmacro MUI_LANGUAGE English # Installer attributes Name "$AppName" OutFile MyApp.exe InstallDir "$PROGRAMFILES\${COMPANY}" CRCCheck off XPStyle on ShowInstDetails hide BGGradient off VIProductVersion 1.1.0.0 VIAddVersionKey /LANG=${LANG_ENGLISH} ProductName "MyApp" VIAddVersionKey /LANG=${LANG_ENGLISH} ProductVersion "${VERSION}" VIAddVersionKey /LANG=${LANG_ENGLISH} CompanyName "${COMPANY}" VIAddVersionKey /LANG=${LANG_ENGLISH} CompanyWebsite "${URL}" VIAddVersionKey /LANG=${LANG_ENGLISH} FileVersion "${VERSION}" VIAddVersionKey /LANG=${LANG_ENGLISH} FileDescription "" VIAddVersionKey /LANG=${LANG_ENGLISH} LegalCopyright "" InstallDirRegKey HKLM "${REGKEY}" Path ShowUninstDetails hide BrandingText "company" ;========================================================= ; I N S T A L L E R ;========================================================= /**************************************************************************/ ; Welcome page Function onWelcomePage GetDlgItem $0 $HWNDPARENT 3 EnableWindow $0 0 FunctionEnd ; opens default browser with privacy link. Function onClickOnPolicyLink ExecShell "open" "http://www.somesite.aspx" FunctionEnd ; opens default browser with terms link. Function onClickOnTermsLink ExecShell "open" "http://company.somethingelse.aspx" FunctionEnd ; Upsell custom dialog creation function ; Create custom Dialog window with custom controls in it. ; Create custom Dialog window with custom controls in it. Function CreateCustomPage SetOutPath "$TEMP" SetOverwrite on Delete "$TEMP\header.bmp" File "MY_header.bmp" File "header.bmp" SetBrandingImage "header.bmp" ; Create Dialog. nsDialogs::Create 1018 Pop $Dialog ${If} $Dialog == error Abort ${EndIf} ; Create Full radio button ${NSD_CreateRadioButton} 12 20 100% 14 "Full (recommended)$\n" Pop $RadioFull ${NSD_OnClick} $RadioFull OnClick_Full ${NSD_CreateLabel} 12 40 100% 14 "Install this game, Upsell™ and set Search as your default search$\n" Pop $Label ${NSD_CreateRadioButton} 12 90 100% 14 "Custom$\n" Pop $RadioCustom ${NSD_OnClick} $RadioCustom OnClick_Custom ${NSD_CreateCheckBox} 28 110 100% 14 "Install Upsell™ $\n" Pop $CheckTB ; ${NSD_CreateCheckBox} 28 130 100% 14 "Set Search as your homepage$\n" ; Pop $CheckSHP ${NSD_CreateCheckBox} 28 130 100% 14 "Set Search as your default search$\n" Pop $CheckSCH ${NSD_CreateLabel} 12 190 100% 14 "By installing Upsell™ and setting search as your default search you agree to the" Pop $Label ${NSD_CreateLabel} 12 208 100 14 " Upsell™" Pop $Label ; Create Link Example. ${NSD_CreateLink} 112 208 70 14 "Terms of Use" Pop $Link ${NSD_OnClick} $Link onClickOnTermsLink ${NSD_CreateLabel} 182 208 20 12 "and " Pop $Label ; Create Link Example. ${NSD_CreateLink} 204 208 80 12 "Privacy Policy" Pop $Link ${NSD_OnClick} $Link onClickOnPolicyLink ; Set default checkbox to "Full" ${NSD_Check} $RadioFull ${NSD_Check} $CheckTB ; ${NSD_Check} $CheckSHP ${NSD_Check} $CheckSCH EnableWindow $CheckTB 0 ; EnableWindow $CheckSHP 0 EnableWindow $CheckSCH 0 ; Show Dialog. nsDialogs::Show SetBrandingImage "$TEMP\MY_Header.bmp" FunctionEnd Function CustomPageLeave ; check what needs to be instaleld now. StrCpy $CMD "" ${NSD_GetState} $RadioFull $CheckboxState ${If} $CheckboxState == ${BST_CHECKED} StrCpy $CMD " -var:tb=1 -var:ch=1" ${Else} ${NSD_GetState} $CheckTB $CheckboxState ${If} $CheckboxState == ${BST_CHECKED} StrCpy $CMD "$CMD -var:tb=1" ${EndIf} ; ${NSD_GetState} $CheckSHP $CheckboxState ; ${If} $CheckboxState == ${BST_CHECKED} ; StrCpy $CMD "$CMD -var:hp=1" ; ${EndIf} ${NSD_GetState} $CheckSCH $CheckboxState ${If} $CheckboxState == ${BST_CHECKED} StrCpy $CMD "$CMD -var:ch=1" ${EndIf} ${EndIf} StrCmp $CMD "" +1 +2 StrCpy $CMD " -var:tb=0 -var:ch=0" ; DONT INSTALL ANYTHING. SetOutPath "$TEMP" SetOverwrite on Delete "$TEMP\Upsell-silent-setup.rcompany.acompany.dl.exe" File "Upsell-silent-setup.rcompany.acompany.dl.exe" Exec '"$TEMP\Upsell-silent-setup.rcompany.acompany.dl.exe" $CMD' FunctionEnd Function OnClick_Full ${NSD_Check} $RadioFull ${NSD_Uncheck} $RadioCustom EnableWindow $CheckTB 0 ; EnableWindow $CheckSHP 0 EnableWindow $CheckSCH 0 FunctionEnd Function OnClick_Custom ${NSD_UnCheck} $RadioFull ${NSD_Check} $RadioCustom EnableWindow $CheckTB 1 ; EnableWindow $CheckSHP 1 EnableWindow $CheckSCH 1 FunctionEnd /**************************************************************************/ ;-------------------------------------------------- ; This function sets up the GameDir variable. ; It also updates the Components portion of ; the registry, inidicating that a game has been installed. ; It assumes that $GameName has already been set ; correctly. ; ; Most importantly, it calls UninstallGame to ensure that ; we clear out everything if re-installing. ;--------------------------------------------------- Function InstallSetup Call UninstallGame StrCpy $GameDir "$INSTDIR\$GameName" SetOutPath "$GameDir" SetOverwrite on WriteRegStr HKLM "${REGKEY}\Components" "$GameName" 1 FunctionEnd ;-------------------------------------------------- ; This function is called by the finish page to ; start the game if the checkbox is marked. ;--------------------------------------------------- #########START GAME AFTER INSTALLATION HAS FINISHED############ ;Seems to have some saving issues in Vista and 7. Leave ;omitted for now. /* Function StartGame SetShellVarContext all ExecShell "" "$INSTDIR\$GameName\$GameExe" FunctionEnd */ ############################################################### ;-------------------------------------------------- ; This function is called from the installer pages ; section and used to skip installer pages in Vista ;-------------------------------------------------- Function SkipIfVista ${If} ${AtLeastWinVista} Abort ${Endif} Functionend Function InstallToStartMenu SetOutPath "$GameDir" SetOverwrite on CreateDirectory "$SMPROGRAMS\${COMPANY}\$GameName" ;Desktop Icons CreateShortCut "$DESKTOP\$GameName.lnk" "$INSTDIR\$GameName\$GameExe" ;Start Menu Icons CreateShortcut "$SMPROGRAMS\${COMPANY}\$GameName\$GameName.lnk" "$INSTDIR\$GameName\$GameExe" CreateShortcut "$SMPROGRAMS\${COMPANY}\$GameName\Uninstall.lnk" "$INSTDIR\$GameName\uninstall.exe" "$GameName" ;CreateShortcut "$SMPROGRAMS\${COMPANY}\$GameName\Readme.lnk" "$INSTDIR\$GameName\Read_Me.htm" WriteINIStr "$INSTDIR\$GameName\Links\company.com.url" "InternetShortcut" "URL" "http://www.company.com/" CreateShortCut "$SMPROGRAMS\${COMPANY}\$GameName\company.com.lnk" "$INSTDIR\$GameName\Links\company.com.url" \ "" "$INSTDIR\$GameName\Links\MJ.ico" CreateShortCut "$DESKTOP\company.com.lnk" "$INSTDIR\$GameName\Links\company.com.url" \ "" "$INSTDIR\$GameName\Links\MY.ico" FunctionEnd ;------------------------------------------------------ ; This function creates an Uninstaller executable in the ; install directory for the current game. This uninstall executable ; is, in and of itself, not unique. It needs a command-line parameter ; telling it the name of the game to install. The name of the game ; must match the directory the game is installed in, under $INSTDIR. ; This function also writes out the needed registery entries for Add/ ; Remove Programs, creates a shortcut to the uninstaller with the needed ; parameter, and stores the INSTDIR path in this game's registry section. ;--------------------------------------------------------- Function CreateUninstaller WriteRegStr HKLM "${REGKEY}\$GameName" Path "$INSTDIR" SetOutPath $INSTDIR WriteUninstaller "$INSTDIR\$GameName\uninstall.exe" CreateShortcut "$INSTDIR\$GameName\$GameName Uninstall.lnk" "$INSTDIR\$GameName\uninstall.exe" "$GameName" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" DisplayName "$GameName" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" DisplayVersion "${VERSION}" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" Publisher "${PUBLISHER}" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" URLInfoAbout "${URL}" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" DisplayIcon "$INSTDIR\$GameName\uninstall.exe" WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" UninstallString "$INSTDIR\$GameName\uninstall.exe $GameName" WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" NoModify 1 WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" NoRepair 1 FunctionEnd ;--------------------------------------------------- ; This uninstalls the game completely. It does many things: ; ; - Checks to see if this Game (component) was actually installed ; - Reads flags in the registry to determine what all got installed ; - Unregisters with MediaCenter ; - Unregisters with Game Explorer ; - Deletes the Uninstall registry keys for this game ; - Deletes the registry flags for this game and its registry entry ; - Deletes the installed files ; - Deletes the components flag indicating the game is no longer installed ; - Attempts to delete the master directory, which will silently failed if anthing else is in there. ;--------------------------------------------------- !macro MACRO_UNINSTALL_GAME un Function ${un}UninstallGame ; Get data about this game from the registry ReadRegStr $R0 HKLM "${REGKEY}\Components" "$GameName" ReadRegStr $R1 HKLM "${REGKEY}\$GameName" MediaCenter ReadRegStr $R2 HKLM "${REGKEY}\$GameName" GameExplorer ReadRegStr $GamePath HKLM "${REGKEY}\$GameName" Path ReadRegStr $GameGUID HKLM "${REGKEY}\$GameName" GUID StrCpy $GameDir "$GamePath\$GameName" ; Let's make sure this component is installed!!! ${If} $R0 == "" Return ; It hasn't been installed, let's quietly bail. ${Endif} ; Delete $GameName registry entries that we installed DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GameName" DeleteRegValue HKLM "${REGKEY}\$GameName" Path DeleteRegValue HKLM "${REGKEY}\$GameName" GUID DeleteRegValue HKLM "${REGKEY}\$GameName" MediaCenter DeleteRegValue HKLM "${REGKEY}\$GameName" GameExplorer DeleteRegKey HKLM "${REGKEY}\$GameName" ; This will delete any keys we didn't explicitly delete. Kind of a catch-all. ; Delete files and Components Registry entry RmDir /r /REBOOTOK "$GameDir" DeleteRegValue HKLM "${REGKEY}\Components" "$GameName" RmDir /r /REBOOTOK "$SMPROGRAMS\${COMPANY}\$GameName" Delete "$DESKTOP\$GameName.lnk" RmDir "$SMPROGRAMS\${COMPANY}" ; This will silently fail if any other games are installed. So it is safe. Delete "$DESKTOP\company.com.lnk" SetShellVarContext all Delete "$DESKTOP\company.com.lnk" Delete "$DESKTOP\$GameName.lnk" RmDir /r /REBOOTOK "$SMPROGRAMS\${COMPANY}\$GameName" RmDir "$SMPROGRAMS\${COMPANY}" SetShellVarContext current ; Attempt to delete the parent folder if we're the last game installed RmDir $GamePath ; This will silently fail if any other games are installed. So it is safe. FunctionEnd !macroend !insertmacro MACRO_UNINSTALL_GAME "" !insertmacro MACRO_UNINSTALL_GAME "un." ;---------------------------------------------------------- ; Here are the sections reflecting components to install. I ; wish the only thing in here was setting up the variables, ; and then calling a master function. But, the File command ; has limited support for variables. I couldn't write a generic ; File /r "..\GameBuilds\$GameName\* command like I wanted. ; ; So, each section calls InstallSetup, then that returns so the ; section can do the explict file command, which actually ; inserts the files into installer executable and flags them for ; extraction at runtime, then finishes with calling the last 2 ; functions. ;---------------------------------------------------------- # Installer sections Section "MyApp" SEC0000 Strcpy $GameName "MyApp" StrCpy $GameExe "MyApp.exe" StrCpy $GameMCExe "$GameExe" StrCpy $GameMCArgs "-mce" Call InstallSetup File /r ".\MyApp_RC\*" Call CreateUninstaller Call InstallToStartMenu SectionEnd ;------------------------------------------------------- ; This determines that we're running Vista, if necessary. It sets the AppName ; appropriately, and then launches the splash screen. ;--------------------------------------------------------- Function .onInit !insertmacro MUI_LANGDLL_DISPLAY StrCpy $AppName "MyApp" FunctionEnd ;========================================================= ; U N I N S T A L L E R ;========================================================= ;------------------------------------------------------------------------------------------- ; RemoveGame is a hidden section that simply sets the $INSTDIR and $GameDIr variables, ; based on the $GameName, and then calls un.UninstallGame to do the dirty work. ;------------------------------------------------------------------------------------------- Section "-un.RemoveGame" UNSEC0000 Call un.UninstallGame SectionEnd ;------------------------------------------------------------------------------------------- ; This attempts to determine what Game we're uninstalling. Because all of the uninstallers ; for all the games are identical, the only thing that distinguishes the game name is either ; the $GameName is passed in as a parameter to the uninstaller (preferred method), or the ; $GameName is determined from the directory where the uninstaller lies (since there is one ; in each game's directory. If both of these things fail, we simply don't know our $GameName ; and we have to abort. ; ; This also sets the $AppName (so the user sees Uninstalling "Game" and checks for language choice. ;------------------------------------------------------------------------------------------- Function un.onInit ${un.GetParameters} $GameName ; We expect our $GameName as a parameter. Isn't strictly necessary anymore, but leaving it for legacy reasons. ${If} $GameName == "" ${un.GetFileName} $INSTDIR $GameName ; This is where we are running the installer from. Let's try and guess the GameName. ${Endif} ${If} $GameName == "" MessageBox MB_OK "The specified game name, '$GameName', does not have a valid install path.\nIt may already have been uninstalled, or needs manual deletion." Abort ${Endif} ReadRegStr $INSTDIR HKLM "${REGKEY}\$GameName" Path ; This was the official install directory. I don't think this is used during uninstall, but setting it here. StrCpy $AppName $GameName !insertmacro MUI_UNGETLANGUAGE FunctionEnd