Why does my NSIS script appear to be skipping over installation pages like MUI_PAGE_INSTFILES when I add custom nsDialog pages? - nsis

Here is my latest NSIS installation script, which has grown into quite a beast.
https://pastebin.com/eSABLLsi
My question is, how can I put all of the sections for HW_DATA_DIR, HW_WORKSPACE_DIR, and possibly %HEADWAVE_ROOT_DIR% into a single page? I am guessing that I would have to use nsDialog somehow. My supervisor wants me to do this because there are so many separate install pages where you have to keep clicking and clicking too many times to complete the installation.
I have tried the following, but adding an nsDialog as Page custom HeadwaveConfiguration does in a function does not seem to fit well within the program flow. Here are my code modifications:
Var headwaveConfigDialog
Var headwaveConfigDataDirLabel
Var headwaveConfigDataDirText
Var headwaveConfigWkDirLabel
Var headwaveConfigWkDirText
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesCheck
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ComponentsLeave
!insertmacro MUI_PAGE_COMPONENTS
## This is the title on the Headwave Data Directory page
;!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_HW)"
;!define MUI_PAGE_HEADER_TEXT "Headwave configuration"
; !define MUI_PAGE_HEADER_SUBTEXT "Select the folder which Headwave can use as a data storage."
Page custom HeadwaveConfiguration
; ; HW Data
; !define MUI_PAGE_CUSTOMFUNCTION_PRE hw_data_pre
; !define MUI_PAGE_CUSTOMFUNCTION_SHOW hw_data_dir
; !define MUI_DIRECTORYPAGE_VARIABLE $HW_DATA_DIR
; !insertmacro MUI_PAGE_DIRECTORY
; ## This is the title on the Headwave Workspace Directory page
; !define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_HW_WK)"
; !define MUI_PAGE_HEADER_TEXT "Choose Headwave Workspace directory"
; !define MUI_PAGE_HEADER_SUBTEXT "Select the folder which Headwave can use as a workspace."
; # HW Workspaces
; !define MUI_PAGE_CUSTOMFUNCTION_PRE hw_wk_pre
; !define MUI_PAGE_CUSTOMFUNCTION_SHOW hw_wk_dir
; !define MUI_DIRECTORYPAGE_VARIABLE $HW_WORKSPACE_DIR
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
## This is the title on the Headwave installation Directory page to obtain directory for %HEADWAVE_ROOT_DIR
!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_HW_INST)"
!define MUI_PAGE_HEADER_TEXT "Choose Headwave Plugin installation directory"
!define MUI_PAGE_HEADER_SUBTEXT "Select the folder where Headwave is presently installed to set environment variable."
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesHeadwaveProg
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
; ...
Function HeadwaveConfiguration
!insertmacro MUI_HEADER_TEXT "Headwave configuration" "Select the respective folders for Headwave."
nsDialogs::Create 1018
Pop $headwaveConfigDialog
${NSD_CreateLabel} 0 0 100% 12u "Select the folder which Headwave can use as a data storage:"
Pop $headwaveConfigDataDirLabel
${NSD_CreateText} 10% 20u 80% 12u "C:\HW-Data"
Pop $headwaveConfigDataDirText
StrCpy $HW_DATA_DIR $headwaveConfigDataDirText
${NSD_CreateLabel} 0 40u 80% 12u "Select the folder which Headwave can use as a workspace:"
Pop $headwaveConfigWkDirLabel
${NSD_CreateText} 10% 60u 80% 12u "C:\HW-Workspaces"
Pop $headwaveConfigWkDirText
StrCpy $HW_WORKSPACE_DIR $headwaveConfigWkDirText
;${NSD_CreateLabel} 0 80u 80% 12u "Select the folder where Headwave is installed:"
;Pop $headwaveConfigProgramDirLabel
;StrCpy $headwaveConfigProgramDirText $HeadwaveInstallDir
;${NSD_CreateText} 10% 100u 80% 12u $HeadwaveInstallDir
;Pop $headwaveConfigProgramDirText
;StrCpy $HeadwaveInstallDir $headwaveConfigProgramDirText
;MessageBox MB_OK 'HeadwaveConfiguration: HeadwaveInstallDir = $HeadwaveInstallDir; headwaveConfigProgramDirText = $headwaveConfigProgramDirText'
SetCtlColors $headwaveConfigHwnd 0xFF0000 0xFFFFFF
nsDialogs::Show
FunctionEnd
But the problem is that it the HeadwaveConfiguration nsDialog page gets calls to obtain HW_DATA_DIR and HW_WORKSPACE_DIR, but then it just jumps to start installing MyApp instead of first installing the Headwave components and then moving on to install MyApp
Does anyone have any suggestions? TIA.
UPDATE:
Here is how I have updated the code, but it still does not install the Headwave components before it jumps to the MyApp install page:
!define MUI_PAGE_CUSTOMFUNCTION_PRE SelectFilesCheck
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ComponentsLeave
!insertmacro MUI_PAGE_COMPONENTS
## This is the title on the Headwave Data Directory page
!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_HW)"
!define MUI_PAGE_HEADER_TEXT "Headwave configuration"
!define MUI_PAGE_CUSTOMFUNCTION_PRE HeadwaveConfigurationPre
!define MUI_PAGE_CUSTOMFUNCTION_SHOW HeadwaveConfigurationShow
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
## This is the title on the Headwave installation Directory page to obtain directory for %HEADWAVE_ROOT_DIR%
!define MUI_DIRECTORYPAGE_TEXT_TOP "$(MUI_DIRECTORYPAGE_TEXT_TOP_HW_INST)"
!define MUI_PAGE_HEADER_TEXT "Choose Headwave Plugin installation directory"
!define MUI_PAGE_HEADER_SUBTEXT "Select the folder where Headwave is presently installed to set environment variable."
Function HeadwaveConfigurationPre
!insertmacro MUI_HEADER_TEXT "Headwave configuration" "Select the respective folders for Headwave."
nsDialogs::Create 1018
Pop $headwaveConfigDialog
${NSD_CreateLabel} 0 0 100% 12u "Select the folder which Headwave can use as a data storage:"
Pop $headwaveConfigDataDirLabel
${NSD_CreateText} 10% 20u 80% 12u "C:\HW-Data"
Pop $headwaveConfigDataDirText
StrCpy $HwDataDir $headwaveConfigDataDirText
${NSD_CreateLabel} 0 40u 80% 12u "Select the folder which Headwave can use as a workspace:"
Pop $headwaveConfigWkDirLabel
${NSD_CreateText} 10% 60u 80% 12u "C:\HW-Workspaces"
Pop $headwaveConfigWkDirText
StrCpy $HwWorkspaceDir $headwaveConfigWkDirText
;${NSD_CreateLabel} 0 80u 80% 12u "Select the folder where Headwave is installed:"
;Pop $headwaveConfigProgramDirLabel
;StrCpy $headwaveConfigProgramDirText $HeadwaveInstallDir
;${NSD_CreateText} 10% 100u 80% 12u $HeadwaveInstallDir
;Pop $headwaveConfigProgramDirText
;StrCpy $HeadwaveInstallDir $headwaveConfigProgramDirText
SetCtlColors $headwaveConfigHwnd 0xFF0000 0xFFFFFF
nsDialogs::Show
FunctionEnd
Function HeadwaveConfigurationShow
MessageBox MB_OK 'HeadwaveConfiguration: HeadwaveInstallDir = $HeadwaveInstallDir; headwaveConfigProgramDirText = $headwaveConfigProgramDirText'
FunctionEnd
## Section 1
Section "MyPartnerApp Plugin" SEC1
MessageBox MB_OK 'Headwave Plugin #1: INSTDIR = $INSTDIR'
${If} ${SectionIsSelected} ${SEC1}
${StrContains} $0 "MyPartnerApp" "$INSTDIR"
StrCmp $0 "" notfoundMyPartnerApp
Goto doneMyPartnerApp
doneMyPartnerApp:
MessageBox MB_OK 'Headwave Plugin #2: HW_DATA_DIR = $HW_DATA_DIR'
SetOutPath "$HW_DATA_DIR"
${StrContains} $0 "Data" "$HW_DATA_DIR"
StrCmp $0 "" notfoundHwData
Goto doneHwData
;MessageBox MB_OK 'Did not find MyApp string'
doneHwData:
##All the files in Group 0 will be installed to the same location, $HW_DATA_DIR
MessageBox MB_OK 'Headwave Plugin #3: HW_DATA_DIR = $HW_DATA_DIR'
SetOutPath "$HW_DATA_DIR"
CreateDirectory "$HW_DATA_DIR"
CreateDirectory "$HW_DATA_DIR\MyApp-Plugins"
CreateDirectory "$HW_DATA_DIR\MyApp-Plugins\ComputePlugin"
CreateDirectory "$HW_DATA_DIR\MyApp-Plugins\ExtensionPlugin"
File /oname=$HW_DATA_DIR\MyApp-Plugins\ComputePlugin\computeplugin.xplot.dll computeplugin.xplot.dll
File /oname=$HW_DATA_DIR\MyApp-Plugins\ComputePlugin\computeplugin.VirtualVolume.dll computeplugin.VirtualVolume.dll
File /oname=$HW_DATA_DIR\MyApp-Plugins\ExtensionPlugin\hwProxyInterface.MyApp.dll hwProxyInterface.MyApp.dll
# MyPartnerApp workspace
CreateDirectory "$HW_WORKSPACE_DIR"
##All the files in Group 1 will be installed to the same location, $INSTDIR
SetOutPath "$INSTDIR"
;messagebox mb_ok "MyPartnerApp Program: INSTDIR is $INSTDIR"
# set environment variable for current user
WriteRegExpandStr ${env_hkcu} HEADWAVE_ROOT_DIR $INSTDIR
# save the selected headwave program directory
StrCpy $MyPartnerAppSelectedInstallDir $INSTDIR
# make sure windows knows about the change
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
# Install Sound-MyApp python scripts
CreateDirectory $INSTDIR\python\hwtoolkits\MyCompany
File __init__.py
File MyAppConfig.py
File MyAppPlugin.py
CopyFiles $INSTDIR\*.py $INSTDIR\python\hwtoolkits\MyCompany
notfoundHwData:
notfoundMyPartnerApp:
; Do nothing
${Else}
Abort
${EndIf}
SectionEnd
I would have thought since HeadwaveConfigurationPre should be called first so that $HW_DATA_DIR should be C:\HW-Data but instead one of the messageboxes I added shows this:
Headwave Plugin #2: HW_DATA_DIR = 6494062
UPDATE 2:
Thanks for the feedback, #Anders.
Here is my latest code, where initially it is getting the values for $HwDataDir and $HwWorkspaceDir:
https://pastebin.com/VsT0MJf1
NOTE: I previously pasted only partial code in https://pastebin.com/DJTLQ05D
Here is a dialog box that shows the values are being obtained initially:
Next it gets to the plugin installation page:
But then eventually, it gets to this line of code:
MessageBox MB_OK 'Headwave Plugin #2: HwDataDir = $HwDataDir'
In which case the $HwDataDir has a number again:
Could you please tell me, how could that happen? Why would the value change from C:\HW-Data to 1181026? TIA.

You cannot use MUI_PAGE_CUSTOMFUNCTION_* with nsDialogs. In your last update $HwDataDir contains a number because it is the handle to the text control, not its text. Even if you asked for its text it would be the wrong time, you should do that in the leave callback. Custom pages only have create and leave callbacks, not pre and show!
Here is part of the example code from the nsDialogs documentation:
Page custom nsDialogsPage nsDialogsPageLeave
Page instfiles
Function nsDialogsPage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $Label
${NSD_CreateText} 0 13u 100% -13u "Type something here..."
Pop $Text
nsDialogs::Show
FunctionEnd
Function nsDialogsPageLeave
${NSD_GetText} $Text $0
MessageBox MB_OK "You typed:$\n$\n$0"
FunctionEnd
Your code contains other issues like
Section "MyPartnerApp Plugin" SEC1
${If} ${SectionIsSelected} ${SEC1}
which makes no sense, you can't check itself like that. The IsPROG0HwDataSelected function is so broken you should rewrite it from scratch with ${If} and a proper section index.
Update 2:
In your new code, StrCpy $HwDataDir $headwaveConfigDataDirText is where it gets "corrupted" with the handle. You don't need StrCpy, all you need in the leave function is ${NSD_GetText} $headwaveConfigDataDirText $HwDataDir.

Related

How to create shortcut for desktop and startmenu after installation in NSIS?

I am new to NSIS. I am trying to add this below style of the page in post-installation (i.e. before the finish page). Could anyone suggest, whether we can do a single custom page and add the necessary checkbox, radio button, and program groups ? or any other suggestions.
Below is my page sequence:
!insertmacro MUI_PAGE_DIRECTORY
;Custom page for selecting service name to restart.
Page custom nsDialogsSelectService ngDialogSelectServicePageLeave
; variable and text for the app data dir
!define MUI_DIRECTORYPAGE_VARIABLE $appDataDir
!define MUI_PAGE_HEADER_TEXT "Choose Data Directory"
!define MUI_PAGE_HEADER_SUBTEXT "Choose the folder in which to install application data for ${PRODUCT_FULL} ${PVERSION}."
!define MUI_DIRECTORYPAGE_TEXT_TOP "Setup will install data directory need todo. To install in a different folder, click Browse and select another folder. Click Next to Continue."
!define MUI_DIRECTORYPAGE_TEXT_DESTINATION "Destination Folder"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_TITLE_3LINES
Page custom nsDialogShortcut ngDialogShortcutPageLeave ;Page contain checkbox , based on the selection of checkbox I am showing Startmenu and then finish page.
!insertmacro MUI_PAGE_STARTMENU 0 $SMDir
!insertmacro MUI_PAGE_FINISH
Giving the user the choice of user/machine shortcuts is in conflict with how UAC works. When a non-admin user elevates with an administrator account the installer will end up running with the "wrong" profile.
The Windows guidelines say that only application suites (with individual major applications, like MS Office) should create Start menu folders. Regular applications should create their (single) shortcut directly in $SMPrograms. You should not create shortcuts to the uninstaller nor help-files. You should also refrain from creating a desktop shortcut.
This means you can simply use the components page to provide the shortcut option(s):
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Section "Program files"
SectionIn RO
SetOutPath $InstDir
File "MyApp.exe"
SectionEnd
Section "Start menu shortcut"
CreateShortcut "$SMPrograms\$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd
Section /o "Desktop shortcut"
CreateShortcut "$Desktop\$(^Name).lnk" "$InstDir\MyApp.exe"
SectionEnd
or as a checkbox on the Finish page:
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_SHOWREADME ""
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Start menu shortcut"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateShortcuts
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function CreateShortcuts
CreateShortcut "$SMPrograms\$(^Name).lnk" "$InstDir\MyApp.exe"
FunctionEnd
If you actually have a suite of applications then you can use the Start menu page to prompt for a folder name:
Var SMFolder
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE STARTMENU Suite $SMFolder
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Section
!insertmacro MUI_STARTMENU_WRITE_BEGIN Suite
CreateDirectory "$SMPrograms\$SMFolder"
CreateShortcut "$SMPrograms\$SMFolder\App1.lnk" "$InstDir\MyApp1.exe"
CreateShortcut "$SMPrograms\$SMFolder\App2.lnk" "$InstDir\MyApp2.exe"
; TODO: Write $SMFolder to the registry or a .ini so your uninstaller can delete the folder
!insertmacro MUI_STARTMENU_WRITE_END
SectionEnd
In the unlikely event that you have a suite of applications and you also want to create desktop shortcuts then yes, you need to use a custom page:
Var SMDir
Var SMCheck
Var DeskCheck
Var SMList
Var SMDirEdit
!include LogicLib.nsh
!include nsDialogs.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyShortcutsPageCreate MyShortcutsPageLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function .onInit
StrCpy $SMDir "$(^Name)" ; Default
StrCpy $SMCheck ${BST_CHECKED}
FunctionEnd
Function MyShortcutsPageCreate
!insertmacro MUI_HEADER_TEXT "Shortcuts" "Shortcuts blah blah blah"
nsDialogs::Create 1018
Pop $0
${IfThen} $0 == error ${|} Abort ${|}
${NSD_CreateCheckbox} 0 0u 50% 12u "Create Start menu shortcuts"
Pop $R8
SendMessage $R8 ${BM_SETCHECK} $SMCheck ""
${NSD_CreateCheckbox} 0 14u 50% 12u "Create desktop shortcuts"
Pop $R9
SendMessage $R9 ${BM_SETCHECK} $DeskCheck ""
${NSD_CreateSortedListBox} 0 28u 100% -43u ""
Pop $SMList
${NSD_CreateText} 0 -13u 100% 12u "$SMDir"
Pop $SMDirEdit
${NSD_LB_AddString} $SMList "(Default)"
${NSD_LB_SetItemData} $SMList 0 1 ; Mark as special
SetShellVarContext Current
Call FillSMList
SetShellVarContext All
Call FillSMList
SetShellVarContext ? ; TODO: Restore to what you actually are installing as
${NSD_OnChange} $SMList OnSMListChanged
${NSD_OnClick} $R8 OnSMCheckChanged
Push $R8
Call OnSMCheckChanged
nsDialogs::Show
FunctionEnd
Function FillSMList
FindFirst $0 $1 "$SMPrograms\*"
loop:
StrCmp $1 "" done
${If} ${FileExists} "$SMPrograms\$1\*.*"
${AndIf} $1 != "."
${AndIf} $1 != ".."
${NSD_LB_FindStringExact} $SMList "$1" $2
${If} $2 < 0
${NSD_LB_AddString} $SMList $1
${EndIf}
${EndIf}
FindNext $0 $1
Goto loop
done:
FindClose $0
FunctionEnd
Function OnSMCheckChanged
Pop $0
${NSD_GetChecked} $0 $0
EnableWindow $SMList $0
EnableWindow $SMDirEdit $0
FunctionEnd
Function OnSMListChanged
Pop $0
${NSD_LB_GetSelection} $SMList $0
${NSD_SetText} $SMDirEdit "$0\$(^Name)"
${NSD_LB_GetSelectionIndex} $SMList $0
${NSD_LB_GetItemData} $SMList $0 $0
${If} $0 <> 0
${NSD_SetText} $SMDirEdit "$(^Name)"
${EndIf}
FunctionEnd
Function MyShortcutsPageLeave
${NSD_GetChecked} $R8 $SMCheck
${NSD_GetChecked} $R9 $DeskCheck
${NSD_GetText} $SMDirEdit $SMDir
FunctionEnd
Section
${If} $SMCheck <> 0
CreateDirectory "$SMPrograms\$SMDir"
CreateShortcut "$SMPrograms\$SMDir\App1.lnk" "$InstDir\App1.exe"
CreateShortcut "$SMPrograms\$SMDir\App2.lnk" "$InstDir\App2.exe"
${EndIf}
${If} $DeskCheck <> 0
CreateShortcut "$Desktop\App1.lnk" "$InstDir\App1.exe"
CreateShortcut "$Desktop\App2.lnk" "$InstDir\App2.exe"
${EndIf}
SectionEnd

NSIS: call MUI_PAGE_LICENSE from function but get "XPStyle not valid" error

I have a custom dialog with an "License terms and conditions." checkbox where the Text to the checkbox is actually a link which is suppose to show the License Dialog.
; === LicenseLink (type: Link) ===
${NSD_CreateLink} 132.96u 100.92u 107.29u 14.15u "License terms and conditions."
Pop $hCtl_welcome_LicenseLink
${NSD_OnClick} $hCtl_welcome_LicenseLink ShowLicense
Now in the function "ShowLicense" I tried calling
!insertmacro MUI_PAGE_LICENSE
but get an error:
Error: command XPStyle not valid in Function
evidently I'm approaching this wrong and I can't interpret the error. Would be happy for any ideas on how to resolve this.
Thanks!
You cannot call !insertmacro MUI_PAGE_LICENSE dynamically, the number of pages is determined at compile time.
You can however skip pages to achieve this:
InstallDir "$Temp\Test"
!include MUI2.nsh
!include nsDialogs.nsh
!include WinMessages.nsh
!include LogicLib.nsh
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipLicensePage
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
Page Custom InfoPageCreate InfoPageValidate
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Var ShowLicensePage
Function SkipLicensePage
${IfThen} $ShowLicensePage = 0 ${|} Abort ${|} ; Skip it the first time
FunctionEnd
Function OnShowLicense
SendMessage $hWndParent ${WM_COMMAND} 3 "" ; Click the (hidden) back button
FunctionEnd
Var InstDirCtl
Function InfoPageCreate
StrCpy $ShowLicensePage 1
GetDlgItem $0 $hWndParent 3
ShowWindow $0 0 ; Hide the back button
!insertmacro MUI_HEADER_TEXT "Blah blah" "blah blah blah"
nsDialogs::Create 1018
Pop $0
${NSD_CreateText} 0 13u 100% 12u "$InstDir"
Pop $InstDirCtl
${NSD_CreateLink} 2u 40u -4u 12u "License"
Pop $0
${NSD_OnClick} $0 OnShowLicense
nsDialogs::Show
FunctionEnd
Function InfoPageValidate
${NSD_GetText} $InstDirCtl $InstDir
FunctionEnd

Added link to MUI_PAGE_INSTFILES does not show

I'm trying to create a downloader that also has a "Download manually" link, but the link does not seem to show.
I tried to follow instructions from this post but can't seem to make it work.
I'm copying the script here in case anyone can point out what I might be missing - I'm a noob in NSIS scripting, sorry.
!include "MUI2.nsh"
!define NAME "instfileslink"
Name "${NAME}"
OutFile "${NAME}.exe"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyInstFilesShow
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Var hCtl_test_Link1
Section
Section
inetc::get /caption "Downloading package" "http://speedtest.ftp.otenet.gr/files/test100Mb.db" "test100Mb.db" /end
Pop $R0
StrCmp $R0 "OK" 0 dlfailed
Quit
dlfailed:
DetailPrint "Download failed: $R0"
Abort
SectionEnd
Function fnLinkClicked
ExecShell "open" "http://speedtest.ftp.otenet.gr/files/test100Mb.db"
FunctionEnd
Function MyInstFilesShow
${NSD_CreateLink} 120u 175u 100% 10u "Download manually"
Pop $hCtl_test_Link1
${NSD_OnClick} $hCtl_test_Link1 fnLinkClicked
FunctionEnd
You cannot use NSDialogs controls (${NSD_Create*}) outside a NSDialogs dialog!
You can use ChangeUI/MUI_UI to add controls to a built-in page or you can add the dynamically at run-time by manually creating a window. You need to use the ButtonEvent plug-in to catch the click events:
!include "MUI2.nsh"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyInstFilesShow
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
!include nsDialogs.nsh ; For style defines
ShowInstDetails hide
Function MyInstFilesShow
FindWindow $0 "#32770" "" $HWNDPARENT ; Find the inner dialog
System::Call 'USER32::CreateWindowEx(i0, t "STATIC", t "Download manually", i${WS_CHILD}|${WS_VISIBLE}|${SS_NOTIFY}, i 100, i 200, i 300, i 50, p $0, i 0x666, p 0, p 0)p.s'
Pop $0
SetCtlColors $0 0000ff transparent
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $1 fnLinkClicked
ButtonEvent::AddEventHandler 0x666 $1
FunctionEnd
Function fnLinkClicked
ExecShell "open" "http://speedtest.ftp.otenet.gr/files/test100Mb.db"
FunctionEnd

NSIS selected options odd behaviour

I am not an NSIS pro but I get by! I am setting up a new installer for a new piece of software we are building, I have configured the installer up with 2 potential paths, install or upgrade.
The idea is that when a user selects any of the upgrade options all options that may be selected for install are deselected and vice versa.
What is happening for me at the moment is when a user for example, selects one option under the install path, all options for that path are being selected and are not deselectable unless you select an option under the upgrade path, after which interestingly, selection of options then appears to behave as wanted?
Here is my code, what obvious thing am I missing here??
;--------------------------------
;Includes
;--------------------------------
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
!include "Sections.nsh"
!include "oledb.nsh"
!include "WinMessages.nsh"
!include "ReplaceInFile.nsh"
;--------------------------------
;General
;--------------------------------
;Name and file
Name "App"
OutFile "AppName ${Version}.exe"
;Default installation folder
InstallDir "C:\appFolder"
;Request application privileges for Windows Vista +
RequestExecutionLevel admin
;--------------------------------
;Interface Settings
;--------------------------------
!define MUI_ABORTWARNING
Var Dialog
Var SQLServer
Var SQLUsername
Var SQLPassword
Var SDatabase
Var CoreDatabase
Var UIDatabase
ShowInstDetails "show"
;--------------------------------
;Pages
;--------------------------------
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "LIC.rtf"
!insertmacro MUI_PAGE_COMPONENTS
Page Custom SQLConnectionDetails SQLConnectionDetailsPageLeave
Page Custom DatabaseDetails DatabaseDetailsLeave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
;onInit
;--------------------------------
Function .onInit
InitPluginsDir
StrCpy $1 "SecMain"
FunctionEnd
;--------------------------------
;Page functions
;--------------------------------
Function SQLConnectionDetails
!insertmacro MUI_HEADER_TEXT $(SQLServerDetailsTitle) $(SQLServerDetailsSubTitle)
nsDialogs::Create 1018
pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
;x, y, width, height and text
${NSD_CreateLabel} 0 0 100% 10u "Enter the name of the SQL server that AppName is to be installed on"
pop $1
${NSD_CreateText} 0 10u 150u 12u ""
pop $SQLServer
${NSD_CreateLabel} 0 25u 100% 10u "Enter the database name"
pop $2
${NSD_CreateText} 0 35u 100u 12u ""
pop $SDatabase
${NSD_CreateLabel} 0 50u 100% 10u "Enter SQL username"
pop $3
${NSD_CreateText}} 0 60u 100u 12u ""
pop $SQLUsername
${NSD_CreateLabel} 0 75u 100% 10u "Enter SQL password"
pop $4
${NSD_CreatePassword} 0 85u 100u 12u ""
pop $SQLPassword
nsDialogs::Show
FunctionEnd
Function SQLConnectionDetailsPageLeave
${NSD_GetText} $SQLServer $SQLServer
${NSD_GetText} $SQLUsername $SQLUsername
${NSD_GetText} $SQLPassword $SQLPassword
${NSD_GetText} $SDatabase $SDatabase
messagebox MB_OK "We will now attempt to connect to the database server."
MSSQL_OLEDB::SQL_Logon "$SQLServer" "$SQLUsername" "$SQLPassword"
pop $0
${If} $0 = 0
;messagebox MB_OK "Connection sucessful"
${Else}
messagebox MB_OK "I encountered an issue whilst trying to connect to the database. Please check your details and try again."
abort
${EndIf}
MSSQL_OLEDB::SQL_Logout
FunctionEnd
Function DatabaseDetails
!insertmacro MUI_HEADER_TEXT $(DatabaseNamesTitle) $(DatabaseNamesSubTitle)
nsDialogs::Create 1018
pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
;x, y, width, height and text
${NSD_CreateLabel} 0 0 100% 10u "Enter the name to be given to the Core database"
pop $1
${NSD_CreateText} 0 10u 150u 12u ""
pop $CoreDatabase
${NSD_CreateLabel} 0 25u 100% 10u "Enter the name to be given to the UI database"
pop $2
${NSD_CreateText} 0 35u 100u 12u ""
pop $UIDatabase
nsDialogs::Show
FunctionEnd
Function DatabaseDetailsLeave
${NSD_GetText} $CoreDatabase $CoreDatabase
${NSD_GetText} $UIDatabase $UIDatabase
FunctionEnd
;--------------------------------
;Languages
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
;--------------------------------
InstType "New Install"
InstType "New Install - Full"
InstType "Upgrade"
;------------
;New Install
;------------
SectionGroup /e "!Install" SecGroupNewInstall
Section "Main App" SecMain
SectionEnd
Section /o "App1" SecApp1
SectionEnd
Section /o "App2" SecApp2
SectionEnd
Section /o "App3" SecApp3
SectionEnd
Section /o "App4" SecApp4
SectionEnd
SectionGroup /e "Optional" SubSecGroupNewInstall
Section /o "App5" SecApp5
SectionEnd
Section /o "App6" SecApp6
SectionEnd
Section /o "App7" SecApp7
SectionEnd
SectionGroupEnd
SectionGroupEnd
SectionGroup /e "!Upgrade" SecGroupUpgrade
Section /o "Upgrade Main App" SecMainUpgrade
SectionEnd
SectionGroupEnd
;--------------------------------
;onSelChange
;--------------------------------
Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${SecMain}
!insertmacro RadioButton ${SecMainUpgrade}
!insertmacro EndRadioButtons
!insertmacro SectionFlagIsSet ${SecMain} ${SF_SELECTED} InstisSel InstnotSel
InstnotSel:
!insertmacro UnselectSection ${SecGroupNewInstall}
InstisSel:
!insertmacro SectionFlagIsSet ${SecMainUpgrade} ${SF_SELECTED} UpgisSel UpgnotSel
UpgnotSel:
!insertmacro UnselectSection ${SecGroupUpgrade}
UpgisSel:
FunctionEnd
I have answered my own question!!
The issue was down to both timing, and an issue with my onInit function. I have moved my onInit function below my section groups and corrected the StrCpy to now include the correct section reference, see corrected code below:
;--------------------------------
;Includes
;--------------------------------
!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
!include "Sections.nsh"
!include "oledb.nsh"
!include "WinMessages.nsh"
!include "ReplaceInFile.nsh"
;--------------------------------
;General
;--------------------------------
;Name and file
Name "App"
OutFile "AppName ${Version}.exe"
;Default installation folder
InstallDir "C:\appFolder"
;Request application privileges for Windows Vista +
RequestExecutionLevel admin
;--------------------------------
;Interface Settings
;--------------------------------
!define MUI_ABORTWARNING
Var Dialog
Var SQLServer
Var SQLUsername
Var SQLPassword
Var SDatabase
Var CoreDatabase
Var UIDatabase
ShowInstDetails "show"
;--------------------------------
;Pages
;--------------------------------
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "LIC.rtf"
!insertmacro MUI_PAGE_COMPONENTS
Page Custom SQLConnectionDetails SQLConnectionDetailsPageLeave
Page Custom DatabaseDetails DatabaseDetailsLeave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
;Page functions
;--------------------------------
Function SQLConnectionDetails
!insertmacro MUI_HEADER_TEXT $(SQLServerDetailsTitle) $(SQLServerDetailsSubTitle)
nsDialogs::Create 1018
pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
;x, y, width, height and text
${NSD_CreateLabel} 0 0 100% 10u "Enter the name of the SQL server that AppName is to be installed on"
pop $1
${NSD_CreateText} 0 10u 150u 12u ""
pop $SQLServer
${NSD_CreateLabel} 0 25u 100% 10u "Enter the database name"
pop $2
${NSD_CreateText} 0 35u 100u 12u ""
pop $SDatabase
${NSD_CreateLabel} 0 50u 100% 10u "Enter SQL username"
pop $3
${NSD_CreateText}} 0 60u 100u 12u ""
pop $SQLUsername
${NSD_CreateLabel} 0 75u 100% 10u "Enter SQL password"
pop $4
${NSD_CreatePassword} 0 85u 100u 12u ""
pop $SQLPassword
nsDialogs::Show
FunctionEnd
Function SQLConnectionDetailsPageLeave
${NSD_GetText} $SQLServer $SQLServer
${NSD_GetText} $SQLUsername $SQLUsername
${NSD_GetText} $SQLPassword $SQLPassword
${NSD_GetText} $SDatabase $SDatabase
messagebox MB_OK "We will now attempt to connect to the database server."
MSSQL_OLEDB::SQL_Logon "$SQLServer" "$SQLUsername" "$SQLPassword"
pop $0
${If} $0 = 0
;messagebox MB_OK "Connection sucessful"
${Else}
messagebox MB_OK "I encountered an issue whilst trying to connect to the database. Please check your details and try again."
abort
${EndIf}
MSSQL_OLEDB::SQL_Logout
FunctionEnd
Function DatabaseDetails
!insertmacro MUI_HEADER_TEXT $(DatabaseNamesTitle) $(DatabaseNamesSubTitle)
nsDialogs::Create 1018
pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
;x, y, width, height and text
${NSD_CreateLabel} 0 0 100% 10u "Enter the name to be given to the Core database"
pop $1
${NSD_CreateText} 0 10u 150u 12u ""
pop $CoreDatabase
${NSD_CreateLabel} 0 25u 100% 10u "Enter the name to be given to the UI database"
pop $2
${NSD_CreateText} 0 35u 100u 12u ""
pop $UIDatabase
nsDialogs::Show
FunctionEnd
Function DatabaseDetailsLeave
${NSD_GetText} $CoreDatabase $CoreDatabase
${NSD_GetText} $UIDatabase $UIDatabase
FunctionEnd
;--------------------------------
;Languages
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
;--------------------------------
InstType "New Install"
InstType "New Install - Full"
InstType "Upgrade"
;------------
;New Install
;------------
SectionGroup /e "!Install" SecGroupNewInstall
Section "Main App" SecMain
SectionEnd
Section /o "App1" SecApp1
SectionEnd
Section /o "App2" SecApp2
SectionEnd
Section /o "App3" SecApp3
SectionEnd
Section /o "App4" SecApp4
SectionEnd
SectionGroup /e "Optional" SubSecGroupNewInstall
Section /o "App5" SecApp5
SectionEnd
Section /o "App6" SecApp6
SectionEnd
Section /o "App7" SecApp7
SectionEnd
SectionGroupEnd
SectionGroupEnd
SectionGroup /e "!Upgrade" SecGroupUpgrade
Section /o "Upgrade Main App" SecMainUpgrade
SectionEnd
SectionGroupEnd
;--------------------------------
;onInit
;--------------------------------
Function .onInit
InitPluginsDir
StrCpy $1 ${SecMain}
FunctionEnd
;--------------------------------
;onSelChange
;--------------------------------
Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${SecMain}
!insertmacro RadioButton ${SecMainUpgrade}
!insertmacro EndRadioButtons
!insertmacro SectionFlagIsSet ${SecMain} ${SF_SELECTED} InstisSel InstnotSel
InstnotSel:
!insertmacro UnselectSection ${SecGroupNewInstall}
InstisSel:
!insertmacro SectionFlagIsSet ${SecMainUpgrade} ${SF_SELECTED} UpgisSel UpgnotSel
UpgnotSel:
!insertmacro UnselectSection ${SecGroupUpgrade}
UpgisSel:
FunctionEnd

NSIS nsDialog has disabled back/next/cancel buttons?

I'm following the NSIS nsDialog tutorial with a goal to gather some user input I will use to write into a config file later. The NSISEclipse plugin has generated an MUI2 template that has gotten me started and successfully installs the files.
I have used the nsDialog tutorial to generate a dialog that does get emitted exactly where I want it to, but for some reason the "Back/Next/Cancel" buttons are all grey. I don't see where in the nsDialog documentation it says to enable/disable those buttons.
Here's my code:
Var Dialog
Var Label
Var MyTextBox
Section configLocationDialog
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $Label
${NSD_CreateText} 10% 20u 80% 12u "Hello World"
Pop $MyTextbox
nsDialogs::Show
SectionEnd
And, the dialog once displayed:
What do I need to change to tell NSIS to allow back/next/cancel?
EDIT More code was asked for. Here's the whole thing as it exists now.
# Auto-generated by EclipseNSIS Script Wizard
# Dec 19, 2013 3:48:34 PM
Name SecureKeypad
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 1.0.0
!define COMPANY **COMPANY**
!define URL http://www.**COMPANY**.com
# MultiUser Symbol Definitions
!define MULTIUSER_EXECUTIONLEVEL Standard
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_INSTDIR $PROGRAMFILES\SecureKeypad
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${REGKEY}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUE "Path"
# MUI Symbol Definitions
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install-colorful.ico"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
!define MUI_STARTMENUPAGE_NODISABLE
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
!define MUI_STARTMENUPAGE_DEFAULTFOLDER SecureKeypad
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall-colorful.ico"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
# Included files
#!include MultiUser.nsh
!include LogicLib.nsh
!include nsDialogs.nsh
!include AdvReplaceInFile.nsh
!include Sections.nsh
!include MUI2.nsh
# Variables
Var StartMenuGroup
# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
# Installer languages
!insertmacro MUI_LANGUAGE English
# Installer attributes
OutFile setup.exe
CRCCheck on
InstallDir $PROGRAMFILES\${COMPANY}\SecureKeypad
XPStyle on
ShowInstDetails show
VIProductVersion 1.0.0.0
VIAddVersionKey ProductName SecureKeypad
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
VIAddVersionKey CompanyWebsite "${URL}"
VIAddVersionKey FileVersion "${VERSION}"
VIAddVersionKey FileDescription ""
VIAddVersionKey LegalCopyright ""
InstallDirRegKey HKLM "${REGKEY}" Path
ShowUninstDetails show
# Input dialogs
Var Dialog
Var Label
Var MyTextbox
#Page custom configLocationDialog configLocationDialogLeave
#Page custom doConfiguration
Section configLocationDialog
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
GetFunctionAddress $0 "configLocationDialogLeave"
nsDialogs::OnBack $Dialog $0
#nsDialogs::OnNext $Dialog
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $Label
${NSD_CreateText} 10% 20u 80% 12u "Hello World"
Pop $MyTextbox
nsDialogs::Show
SectionEnd
Function configLocationDialogLeave
${NSD_GetText} $MyTextbox $0
MessageBox mb_ok $0
FunctionEnd
# Installer sections
Section -Main SEC0000
SetOutPath $INSTDIR
SetOverwrite on
File installable-content\CYBSSecurity.dll
File installable-content\SecureKeypad.exe
File installable-content\SecureKeypad.exe.config
File installable-content\SecureKeypad.config
File installable-content\SecureKeypad.frmSecureKeypad.resources
WriteRegStr HKLM "${REGKEY}\Components" Main 1
!insertmacro AdvReplaceInFile $INSTDIR\SecureKeypad.exe.config "##configFile##" $INSTDIR
SectionEnd
Section -post SEC0001
WriteRegStr HKLM "${REGKEY}" Path $INSTDIR
SetOutPath $INSTDIR
WriteUninstaller $INSTDIR\uninstall.exe
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
SetOutPath $SMPROGRAMS\$StartMenuGroup
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe
!insertmacro MUI_STARTMENU_WRITE_END
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
SectionEnd
# Macro for selecting uninstaller sections
!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
Push $R0
ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}"
StrCmp $R0 1 0 next${UNSECTION_ID}
!insertmacro SelectSection "${UNSECTION_ID}"
GoTo done${UNSECTION_ID}
next${UNSECTION_ID}:
!insertmacro UnselectSection "${UNSECTION_ID}"
done${UNSECTION_ID}:
Pop $R0
!macroend
# Uninstaller sections
Section /o -un.Main UNSEC0000
Delete /REBOOTOK $INSTDIR\SecureKeypad.frmSecureKeypad.resources
Delete /REBOOTOK $INSTDIR\SecureKeypad.exe.config
Delete /REBOOTOK $INSTDIR\SecureKeypad.exe
Delete /REBOOTOK $INSTDIR\<sensored>.dll
DeleteRegValue HKLM "${REGKEY}\Components" Main
SectionEnd
Section -un.post UNSEC0001
DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk"
Delete /REBOOTOK $INSTDIR\uninstall.exe
DeleteRegValue HKLM "${REGKEY}" StartMenuGroup
DeleteRegValue HKLM "${REGKEY}" Path
DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components"
DeleteRegKey /IfEmpty HKLM "${REGKEY}"
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
RmDir /REBOOTOK $INSTDIR
SectionEnd
# Installer functions
Function .onInit
InitPluginsDir
FunctionEnd
# Uninstaller functions
Function un.onInit
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
!insertmacro SELECT_UNSECTION Main ${UNSEC0000}
FunctionEnd
Calling nsDialogs::Create/Show in a section is never valid, they can only be called in the create callback function of a custom page.
Some buttons will be disabled after the instfiles page (Already installed, cannot cancel or go back) but this is done by NSIS itself, not nsDialogs...
If you put your call to nsDialogs:Create in a section it will be run when the installer is installing files and such. In that state you won't be able to keep navigating through the pages in the installer and you are stuck.
Your notice about your custom page running at the end of the installer is really what you should be trying to fix, not dismissing it as the wrong way (it's the only way). NSIS-scripts are quite simple in many ways. For example, pages are loaded in the order that they are declared. So when you declare that you want MUI_PAGE_WELCOME, MUI_PAGE_DIRECTORY and the others you are also setting the order of them.
# Installer pages
!insertmacro MUI_PAGE_WELCOME # First page
!insertmacro MUI_PAGE_DIRECTORY # Second page
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup # Third page
!insertmacro MUI_PAGE_INSTFILES # Etc
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
So if you then try to keep all your code together and add your custom page alongside the functions that handle it, it will undoubtedly be the last page in that order.
# Installer pages
!insertmacro MUI_PAGE_WELCOME # First page
!insertmacro MUI_PAGE_DIRECTORY # Second page
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup # Third page
...
# Input dialogs
Var Dialog
Var Label
Var MyTextbox
Page custom configLocationDialog configLocationDialogLeave # Last page
Section configLocationDialog
nsDialogs::Create 1018
Pop $Dialog
So to illustrate this I took your code and brewed it down to basically the page you wanted.
# Included files
!include LogicLib.nsh
!include nsDialogs.nsh
!include Sections.nsh
!include MUI2.nsh
# Installer pages
!insertmacro MUI_PAGE_WELCOME # First page
Page custom configLocationDialog configLocationDialogLeave # Second page!
!insertmacro MUI_PAGE_FINISH # Last page
# Installer languages
!insertmacro MUI_LANGUAGE English
# Input dialogs
Var Dialog
Var Label
Var MyTextbox
Function configLocationDialog
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
GetFunctionAddress $0 "configLocationDialogLeave"
nsDialogs::OnBack $Dialog $0
${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
Pop $Label
${NSD_CreateText} 10% 20u 80% 12u "Hello World"
Pop $MyTextbox
nsDialogs::Show
FunctionEnd
Function configLocationDialogLeave
${NSD_GetText} $MyTextbox $0
MessageBox mb_ok $0
FunctionEnd
Section -Main SEC0000
SectionEnd
The NSISEclipse plugin generates a lot of code, including a set of macros that execute the various pages that are displayed:
# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
The trick is to inject the page call at the right step.
# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
Page custom configLocationDialog configLocationDialogLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

Resources