Joe Baker
Joe Baker

Reputation: 196

NSIS default install directory -- want to choose based upon install options

I'm pretty much of a novice with NSIS; but I've got a problem, and I've already looked at everything I can find on this site, as well as googling to look for answers; and so far I've got nothing.

I have an NSIS install package that I've been asked to expand so that it will install any of four related programs. However, while related, they each should install to a different folder.

I have a MUI_INSTALLOPTIONS_READ that defines four (mutually exclusive) radio buttons, and that works fine; and it does wait until after that selection to prompt for the install location. But it won't let me set different folders for each app.

The first thing I do in each branch after the MUI_INSTALLOPTIONS_READ is to set $INSTDIR to the default path for the selected application; so I would expect to use that string as the default when it calls the InstallDir; but it doesn't -- it's blank.

Of course I can't move the MUI_INSTALLOPTIONS_READ before the InstallDir in the code, because it must be in a Section; and I can't move the InstallDir after the MUI_INSTALLOPTIONS_READ, because it CANNOT be in a Section (or a Function). I have tried splitting the section that contains the MUI_INSTALLOPTIONS_READ, so that there's some space between it and the next section, and inserting the InstallDir in that space; but that changed nothing.

Anyone know of a way to do what I'm trying to do? Thanks for any suggestions you can offer.

!ifndef PRODUCT_VERSION
  !error "Version required   !  Usage: makensisw.exe /DPRODUCT_VERSION=version scriptfile.nsi"
!endif

; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "ProductX"
!define PRODUCT_PUBLISHER "ACME Technologies"
!define PRODUCT_WEB_SITE "http://www.google.com"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_NAME}.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"

; MUI 1.67 compatible ------
!include "MUI.nsh"

; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"

; Welcome page
!insertmacro MUI_PAGE_WELCOME
; Full Install or Demo page
 Page custom FIOrDemo
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES

; Language files
!insertmacro MUI_LANGUAGE "English"

;Reserve Files
 ReserveFile "appSelect.ini"
  !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS

;   Variables
Var APP1_INSTALL
Var APP2_INSTALL
Var APP3_INSTALL
Var APP4_INSTALL

; MUI end ------


Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Setup.exe"
  InstallDir $INSTDIR
  ; InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
  ShowInstDetails show
  ShowUnInstDetails show

Section "Main    Section" SEC01
 SetOutPath "$INSTDIR"
 SetOverwrite try
 SetShell   VarContext all

  ; pop $0
;   ${While} $0       != "Marker"
;     DetailPrint 'Extra info: $0'
;     pop $0
;   ${EndWhile}
;   Pop $0     ; restore

    !insertmacro MUI_INSTALLOPTIONS_READ $APP2_INSTALL "appSelect.ini" "Field 2" "State"
    !insertmacro MUI_INSTALLOPTIONS_READ $APP1_INSTALL "appSelect.ini" "Field 3" "State"
    !insertmacro MUI_INSTALLOPTIONS_READ $APP3_INSTALL "appSelect.ini" "Field 4" "State"
    !insertmacro MUI_INSTALLOPTIONS_READ $APP4_INSTALL "appSelect.ini" "Field 5" "State"
  DetailPrint 'Install selection $APP2_INSTALL $APP1_INSTALL $APP3_INSTALL $APP4_INSTALL '
     StrCmp $APP1_INSTALL 1 app1_selected
     StrCmp $APP2_INSTALL 1 app2_selected 
     StrCmp $APP3_INSTALL 1 app3_selected
     StrCmp $APP4_INSTALL 1 app4_selected
  Goto continue

app1_selected:
  Strcpy $INSTDIR  "$PROGRAMFILES\Folder1"
  Call InstallApp1
  Goto continue

app2_selected:
  Strcpy $INSTDIR  "$PROGRAMFILES\Folder2"
  Call InstallApp2
  Goto continue

app3_selected:
  Strcpy $INSTDIR  "$PROGRAMFILES\Folder3"
  Call InstallApp3
  Goto continue

app4_selected:
  Strcpy $INSTDIR  "$PROGRAMFILES\Folder4"
  Call InstallApp4
  Goto continue

continue:


SectionEnd


Section -Post
  ; Force reboot after install
  MessageBox MB_ICONINFORMATION|MB_OK "Installation complete.  Your computer will now restart."
  ;  Reboot
SectionEnd

Function InstallApp1
 ;Copy all application files
FunctionEnd

Function InstallApp2
 ;Copy all application files
FunctionEnd

Function InstallApp3
  ;Copy all application files
FunctionEnd

Function InstallApp4
 ;Copy all application files
FunctionEnd

Function .onInit
  ;Extract InstallOptions INI files
    !insertmacro MUI_INSTALLOPTIONS_EXTRACT "appSelect.ini"
FunctionEnd

Function FIOrDemo
    !insertmacro MUI_HEADER_TEXT "Choose Installation Type" ""
    !insertmacro MUI_INSTALLOPTIONS_DISPLAY "appSelect.ini"
FunctionEnd

Upvotes: 0

Views: 2216

Answers (1)

Anders
Anders

Reputation: 101764

Try setting $InstDir in the leave callback for your custom page or the pre callback for the directory page. I would also recommend that you use a section for each app, then you could do all the configuration before you get to the instfiles page.

It is also possible to use the components page with the radio helper macros in sections.nsh instead of your custom page...

!include MUI.nsh
!include LogicLib.nsh
Page Custom MyCustomPageCreate MyCustomPageLeave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English

Function .onInit
InitPluginsDir
WriteIniStr "$PluginsDir\page.ini" Settings NumFields 2
WriteIniStr "$PluginsDir\page.ini" "Field 1" Type RadioButton
WriteIniStr "$PluginsDir\page.ini" "Field 1" Text "App 1"
WriteIniStr "$PluginsDir\page.ini" "Field 1" State 1
WriteIniStr "$PluginsDir\page.ini" "Field 1" Left 20
WriteIniStr "$PluginsDir\page.ini" "Field 1" Right -10
WriteIniStr "$PluginsDir\page.ini" "Field 1" Top 20
WriteIniStr "$PluginsDir\page.ini" "Field 1" Bottom 40
WriteIniStr "$PluginsDir\page.ini" "Field 2" Type RadioButton
WriteIniStr "$PluginsDir\page.ini" "Field 2" Text "App 2"
WriteIniStr "$PluginsDir\page.ini" "Field 2" Left 20
WriteIniStr "$PluginsDir\page.ini" "Field 2" Right -10
WriteIniStr "$PluginsDir\page.ini" "Field 2" Top 40
WriteIniStr "$PluginsDir\page.ini" "Field 2" Bottom 60
FunctionEnd

Function MyCustomPageCreate
!insertmacro INSTALLOPTIONS_DISPLAY "page.ini"
FunctionEnd

Function MyCustomPageLeave
!insertmacro MUI_INSTALLOPTIONS_READ $0 "page.ini" "Field 1" "State"
${If} $0 <> 0
    StrCpy $InstDir "$ProgramFiles\App1"
${Else}
    StrCpy $InstDir "$ProgramFiles\App2"
${EndIf}
FunctionEnd

Upvotes: 1

Related Questions