When I am clicking on "Finish" button or close button at the top right corner of the custom page, page is not closing using NSIS - nsis

I am facing a weird problem, I have added a new custom page (MyAbruptPage). When clicking on "Finish" button or close button at the top right corner of this custom page, page is not closing.
Scenario:
When Installing the software, if something went wrong and installation hasn't done properly it shows a MessageBox from INSTFILES page. Upon click on "OK" on the message box It is navigating to the "Abrupt" page. In the Abrupt Page it is showing "Finish" button, but when clicked on "Finish" the page is not closing instead it is showing a pop-up message (Are you sure you want to close?). Even when i clicked on close button in the top right corner also i am getting the same pop-up message. I don't want that message and the dialog should be closed when clicked on "Finish" button.
Observations:
I am thinking that the problem is due to the sequence of the pages. Because here i have used two custom pages (MyInfoPage, And MyAbruptPage).
If I replace the first page (MyInfoPage) with MyAbruptPage. Then I am not seeing any issue when clicking on "Finish" button in the Abrupt Page.
Below is my code snippet showing pages and its sequence:
Page Custom MyInfoPage ; First Custom page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage ; Second Custom Page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; Below is my code for the Abrupt page
Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0 ; Hide Next button
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ; Hide Back button
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(AbruptTitle)"
Pop $AbruptPageTitle
;SetCtlColors $InterruptPageTitle "" "${MUI_BGCOLOR}"
CreateFont $AbruptPageFont "$(^Font)" "12" "700"
SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(AbruptText)"
Pop $AbruptPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Below is the section and from here Message box is popping up and navigating to the Abrupt screen:
;!insertmacro MUI_LANGUAGE "English"
Section MySection
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "Installation hasn't done properly" IDOK
Call AbruptLeave
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
SectionEnd
;Below is the code for the custompage "MyInfoPage"
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0 ; Hide Next button
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "$(InterruptTitle)"
Pop $InterruptPageTitle
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "$(InterruptText)"
Pop $InterruptPageText
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0 ; Hide Back button
FunctionEnd
Function onAbort
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to close?" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
I have tried by changing the sequence of the pages and every time I am observing different behaviors in both the custom pages. Please help me how to resolve this issue? And the correct way to implement this functionality.
Thank you in advance...
Below is the complete code and it is compiling:
Var PageId
Var PrintBtn
Var Image
Var ImageHandle
Var MyInfoPageTitle
Var MyInfoPageFont
var MyInfoPageText
var IsOnAbruptPage
Var AbruptPageTitle
Var AbruptPageFont
var AbruptPageText
!define MUI_CUSTOMFUNCTION_ABORT onAbort
!include "MUI2.nsh"
!include x64.nsh
Name "MyApp"
OutFile "MyApp.exe"
InstallDir "$PROGRAMFILES32\MyApp"
InstallDirRegKey HKLM "Software\MyApp" "Install_Dir"
RequestExecutionLevel admin
!include LogicLib.nsh
;--------------------------------
Page Custom MyInfoPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!define MUI_TEXT_WELCOME_INFO_TITLE $(welcometitle)
!define MUI_TEXT_WELCOME_INFO_TEXT $(welcometext)
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!define MUI_LICENSEPAGE_CHECKBOX ""
!define MUI_INNERTEXT_LICENSE_BOTTOM ""
!define MUI_INNERTEXT_LICENSE_TOP ""
!define MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX ""
!define MUI_TEXT_LICENSE_TITLE $(licensetitle)
!define MUI_TEXT_LICENSE_SUBTITLE $(licensesubtitle)
!define MUI_LICENSEPAGE_CHECKBOX_TEXT $(licensecheckboxtext)
!insertmacro MUI_PAGE_LICENSE "C:\Program Files (x86)\NSIS\Docs\Modern UI 2\license.txt"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!define MUI_DIRECTORYPAGE_TEXT_TOP $(mydirtoptext)
!define MUI_TEXT_DIRECTORY_TITLE $(mydirtitle)
!define MUI_TEXT_DIRECTORY_SUBTITLE $(mydirsubtitle)
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
!insertmacro MUI_PAGE_INSTFILES
!define MUI_TEXT_FINISH_INFO_TITLE $(Finishpagetitle)
!define MUI_TEXT_FINISH_INFO_TEXT $(Finishpagesubtitle)
!define MUI_FINISHPAGE_RUN ""
!define MUI_FINISHPAGE_RUN_TEXT $(FinishonlineReg)
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_INSTFILES
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
Function .onInit
InitPluginsDir
FunctionEnd
Function MyDirectoryShowCallback
StrCpy $PageId 3
GetDlgItem $0 $hwndparent 1 ;
SendMessage $0 ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd
Function MyLicenseShowCallback
StrCpy $PageId 2
GetDlgItem $0 $hwndparent 2
System::Call *(i,i,i,i)p.r1
System::Call 'USER32::GetWindowRect(pr0,pr1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(p$hwndparent,pr1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
IntOp $2 $4 / 5
System::Call 'USER32::CreateWindowEx(i 0,t "Button",t "Print",i ${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},i r2,i r3,i r4,i r5,p $hwndparent,p 0x666,p 0,p 0)p.r0'
StrCpy $PrintBtn $0
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
!define MUI_WELCOMEPAGE_TITLE_HEIGHT 38
!define /math MUI_WELCOMEPAGE_TEXT_TOP 17 + ${MUI_WELCOMEPAGE_TITLE_HEIGHT}
${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"
Pop $MyInfoPageTitle
CreateFont $MyInfoPageFont "$(^Font)" "12" "700"
SendMessage $MyInfoPageTitle ${WM_SETFONT} $MyInfoPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard was interrupted"
Pop $MyInfoPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
Function onAbort
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
Function AbruptShow
StrCpy $IsOnAbruptPage 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function AbruptLeave
StrCpy $IsOnAbruptPage 0
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u ${MUI_WELCOMEPAGE_TITLE_HEIGHT}u "Setup Wizard ended prematurely"
Pop $AbruptPageTitle
CreateFont $AbruptPageFont "$(^Font)" "12" "700"
SendMessage $AbruptPageTitle ${WM_SETFONT} $AbruptPageFont 0
${NSD_CreateLabel} 120u ${MUI_WELCOMEPAGE_TEXT_TOP}u 195u 130u "Setup Wizard ended prematurely"
Pop $AbruptPageText
Pop $0
nsDialogs::Show
${NSD_FreeImage} $ImageHandle
FunctionEnd
SectionIn RO
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK
Call AbruptLeave
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
SectionEnd
Section "Uninstall"
SectionEnd

The MessageBox you see is coming from your own code in your onAbort function!
The fact that you are doing
!define MUI_PAGE_CUSTOMFUNCTION_SHOW AbruptShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE AbruptLeave
shows that you have don't understand how custom pages work.
To make your special abort page quit without further action you simple have to do nothing in your onAbort function when you are on that page:
Var PageId
var IsOnAbruptPage
!define MUI_CUSTOMFUNCTION_ABORT onAbort
!include "MUI2.nsh"
!include LogicLib.nsh
Name "MyApp"
#OutFile "MyApp.exe"
InstallDir "$temp\MyApp"
#RequestExecutionLevel admin
OutFile Test.exe
RequestExecutionLevel user
;--------------------------------
Page Custom MyInfoPage
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelShow
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyLicenseShowCallback
!insertmacro MUI_PAGE_LICENSE "${__FILE__}"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirectoryShowCallback
!insertmacro MUI_PAGE_DIRECTORY
Page Custom MyAbruptPage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
!insertmacro MUI_LANGUAGE "English"
Function MyDirectoryShowCallback
StrCpy $PageId 3
GetDlgItem $0 $hwndparent 1 ;
SendMessage $0 ${WM_SETTEXT} 0 `STR:$(^NextBtn)`
FunctionEnd
Function MyLicenseShowCallback
StrCpy $PageId 2
FunctionEnd
Function WelShow
StrCpy $PageId 1
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
FunctionEnd
Function MyInfoPage
${IfThen} $PageId == "" ${|} Abort ${|}
StrCpy $PageId 0
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u 28u "Setup Wizard was interrupted"
Pop $0
nsDialogs::Show
FunctionEnd
Function onAbort
${If} $IsOnAbruptPage <> 0 ; If on aborted page
Return ; allow simple exit
${EndIf}
${If} $PageId <> 0
${If} ${Cmd} ` MessageBox MB_YESNO "Are you sure you want to CANCEL" IDYES `
SendMessage $HWNDPARENT 0x408 -$PageId ""
${EndIf}
Abort
${EndIf}
FunctionEnd
Function GoToAbruptPage
StrCpy $IsOnAbruptPage 1
SendMessage $HWNDPARENT 0x408 -1 ""
Abort
FunctionEnd
Function MyAbruptPage
${IfThen} $IsOnAbruptPage == "" ${|} Abort ${|}
GetDlgItem $0 $HWNDPARENT 1
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 3
ShowWindow $0 0
GetDlgItem $0 $HWNDPARENT 2
${NSD_SetText} $0 "Finish"
nsDialogs::Create 1044
Pop $0
${NSD_CreateLabel} 120u 10u 195u 20u "Setup Wizard ended prematurely"
Pop $0
${NSD_CreateLabel} 120u 120u 195u 20u "Setup Wizard ended prematurely"
Pop $0
nsDialogs::Show
FunctionEnd
;--------------------------------
Section "$(^Name) (required)"
SectionIn RO
SetOutPath $INSTDIR
MessageBox MB_OK|MB_ICONEXCLAMATION "There is an installation failure. Aborting the installation process" IDOK
Call GoToAbruptPage
SectionEnd

Related

is it possible in nsis from the dialog to pass the input value as a parameter to the called console application through the installer,

is it possible in nsis from the dialog to pass the input value as a parameter to the called console application through the installer, using the nsDialog plugin
Function customPage
!insertmacro MUI_HEADER_TEXT "Something" "Tool"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "enter text name"
Pop $0
Function customPage
!insertmacro MUI_HEADER_TEXT "Something" "Tool"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "enter text name"
Pop $0
${NSD_CreateText} 0 12u 93% 12u
Pop $TextBox
nsDialogs::Show
FunctionEnd
nsDialogs::Show
FunctionEnd
Yes this is a common pattern. Just save the value when the user leaves the page so you can use it in a Section:
!include MUI2.nsh
!include nsDialogs.nsh
Page Custom MyPageCreate MyPageLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Var TextBox
Var CustomValue
Function .onInit
StrCpy $CustomValue "Hello World" ; Default value used by silent installer
FunctionEnd
Function MyPageCreate
!insertmacro MUI_HEADER_TEXT "Something" "Tool"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "enter text name"
Pop $0
${NSD_CreateText} 0 12u 93% 12u "$CustomValue"
Pop $TextBox
nsDialogs::Show
FunctionEnd
Function MyPageLeave
${NSD_GetText} $TextBox $CustomValue
FunctionEnd
Section
Exec '"$sysdir\cmd.exe" /K echo.$CustomValue&pause&exit'
SectionEnd

Customizing an exsisting NSIS MUI2 page using nsDialogs

I want to include custom controls to Finish Page, depending on IfRebootFlag is set or not, but I don't know why some of those are created but not displayed.
The $hWnd is for each added control a number != 0, so it means all the controls were created. The position of controls seems to be ok... surely it is not behind the image on the left, because the Left coordinate is high enough to put the controls beyond the image
I tried for hours without understanding which can be the problem
;--------------------------------
;Header Files
!include nsDialogs.nsh
!include LogicLib.nsh
!include MUI2.nsh
Name App
OutFile ctmFinishPage.exe
XPStyle on
;--------------------------------
;General
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
;--------------------------------
;Variables
Var hWndChkBoxRunApp
Var hWndChkBoxLinkApp
Var hWndHlineReboot
Var hWndLblReboot
Var hWndRadBtnRebootNow
Var hWndRadBtnRebootLater
Var ctlLeft
Var ctlTop
Var ctlWidht
Var ctlHeight
Var ctlText
;--------------------------------
;Pages
;install pages
!insertmacro MUI_PAGE_INSTFILES
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyFinishShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE MyFinishLeave
!insertmacro MUI_PAGE_FINISH
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section
SetRebootFlag true
SectionEnd
;--------------------------------
;Functions
Function MyFinishShow
;add custom Reboot section to Finish page (MUI_FINISHPAGE_NOREBOOTSUPPORT flag is required)
IfRebootFlag 0 noreboot
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy $0 50
StrCpy $ctlTop $0u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Create Desktop shortcut"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
StrCpy $1 117
StrCpy $ctlTop $1u
StrCpy $R1 1
StrCpy $ctlHeight $R1u
StrCpy $ctlText ""
${NSD_CreateHLine} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndHlineReboot
IntOp $R1 $R1 + 4
IntOp $2 $1 + $R1
StrCpy $ctlTop $2u
StrCpy $R2 25
StrCpy $ctlHeight $R2u
StrCpy $ctlText "Your computer must be restarted in order to complete the installation of App. Do you want to reboot now?"
${NSD_CreateLabel} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndLblReboot
SetCtlColors $hWndLblReboot "" "ffffff"
IntOp $R2 $R2 + 8
IntOp $3 $2 + $R2
StrCpy $ctlTop $3u
StrCpy $R3 10
StrCpy $ctlHeight $R3u
StrCpy $ctlText "Reboot now"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootNow
SetCtlColors $hWndRadBtnRebootNow "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
IntOp $R3 $R3 + 9
IntOp $4 $3 + $R3
StrCpy $ctlTop $4u
StrCpy $R4 10
StrCpy $ctlHeight $R4u
StrCpy $ctlText "I want to manually reboot later"
${NSD_CreateRadioButton} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndRadBtnRebootLater
SetCtlColors $hWndRadBtnRebootLater "" "ffffff"
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
${NSD_OnChange} $hWndRadBtnRebootNow ToggleRadBtnState
${NSD_OnChange} $hWndRadBtnRebootLater ToggleRadBtnState
Goto end
noreboot:
StrCpy $ctlLeft 120u
StrCpy $ctlWidht 61%
StrCpy $0 110
StrCpy $ctlTop $0u
StrCpy $R0 10
StrCpy $ctlHeight $R0u
StrCpy $ctlText "Run App"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxRunApp
SetCtlColors $hWndChkBoxRunApp "" "ffffff"
${NSD_SetState} $hWndChkBoxRunApp ${BST_UNCHECKED}
IntOp $R0 $R0 + 9
IntOp $1 $0 + $R0
StrCpy $ctlTop $1u
StrCpy $R1 10
StrCpy $ctlHeight $R1u
StrCpy $ctlText "Create Desktop"
${NSD_CreateCheckBox} $ctlLeft $ctlTop $ctlWidht $ctlHeight $ctlText
Pop $hWndChkBoxLinkApp
SetCtlColors $hWndChkBoxLinkApp "" "ffffff"
${NSD_SetState} $hWndChkBoxLinkApp ${BST_CHECKED}
${NSD_OnChange} $hWndChkBoxRunApp ToggleChkBoxState
${NSD_OnChange} $hWndChkBoxLinkApp ToggleChkBoxState
end:
FunctionEnd
Function MyFinishLeave
;reboot the PC if radio button for "Reboot Now" option is checked (MUI_FINISHPAGE_NOREBOOTSUPPORT flag needed)
IfRebootFlag 0 noreboot
${NSD_GetState} $hWndChkBoxLinkApp $0
${If} $0 == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
${NSD_GetState} $hWndRadBtnRebootNow $0
${If} $0 == ${BST_CHECKED}
;Reboot
MessageBox MB_OK "Reboot..."
${EndIf}
Goto end
noreboot:
${NSD_GetState} $hWndChkBoxRunApp $0
${If} $0 == ${BST_CHECKED}
Call LaunchAppFile
${EndIf}
${NSD_GetState} $hWndChkBoxLinkApp $0
${If} $0 == ${BST_CHECKED}
Call CreateDesktopShortcut
${EndIf}
end:
FunctionEnd
Function ToggleChkBoxState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop $1 ;$1 = $hWndChkBoxRunApp/LinkApp
${NSD_GetState} $1 $0
${If} $0 == ${BST_CHECKED}
${NSD_SetState} $1 ${BST_UNCHECKED}
${Else}
${NSD_SetState} $1 ${BST_CHECKED}
${EndIf}
FunctionEnd
Function ToggleRadBtnState
;manage Reboot radio buttons state. If one is checked, the other one is not checked and the other way around
Pop $1 ;$1 = $hWndRadBtnRebootNow/Later
${NSD_GetState} $1 $0
${If} $0 == ${BST_CHECKED}
${If} $1 == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_UNCHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_UNCHECKED}
${EndIf}
${Else}
${If} $1 == $hWndRadBtnRebootNow
${NSD_SetState} $hWndRadBtnRebootLater ${BST_CHECKED}
${Else}
${NSD_SetState} $hWndRadBtnRebootNow ${BST_CHECKED}
${EndIf}
${EndIf}
FunctionEnd
Function LaunchAppFile
;create a file batch at runtime for launching an excel instance pointing to the App file name
MessageBox MB_OK "App launched at runtime..."
FunctionEnd
Function CreateDesktopShortcut
;create App shortcut on DESKTOP folder with custom icon
MessageBox MB_OK "Desktop Shortcut created..."
FunctionEnd
No error message is received during displaying Finish page
EDIT: Solved using User32::SetWindowPos API function in order to modify the Custom controls Z-order
!define HWND_TOP 0
!define SWP_NOSIZE 0x0001
!define SWP_NOMOVE 0x0002
System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($hWndCtmCtl, ${HWND_TOP}, 0, 0, 0, 0, ${SWP_NOSIZE}|${SWP_NOMOVE})"
$mui.FinishPage.Text MUI static control with ${MUI_FINISHPAGE_TEXT} text is displaying on top of some of your controls.
Hide it with
Function MyFinishShow
ShowWindow $mui.FinishPage.Text 0
...
Or make it transparent if you want to keep the text and see your controls under it. You would have to move the checkbox down a bit if you want to keep the text so that they don't overlap.
Function MyFinishShow
SetCtlColors $mui.FinishPage.Text "${MUI_TEXTCOLOR}" transparent
...

How to move NSD_OnBack function from the section in NSIS

I'm writing an NSIS script, in this using some sections to execute EXE files. on depending output, I need to go back from the section to other custom pages but here nsis is moving to another section even though keeping of NSD_OnBack function or just calling the particular function
I have tried below 2 methods.
${NSD_OnBack} "callbackfunction"
call callbackfunction
//Section started
Section "validation" VALIDATION
DetailPrint "Executing Validation"
File "Folder_name\Validation.exe"
nsExec::Exec '"$INSTDIR\Validation.exe" $arg1 $arg2 $arg3'
IfFileExists "$INSTDIR\Output.txt" pass fail
pass:
FileOpen $chk "$INSTDIR\Output.txt" r
FileRead $chk $1
MessageBox MB_OK|MB_ICONSTOP "Validation_Output : in 1 $1"
Push $1
Push "true"
Call StrContains
Pop $3
${If} $3 == "true"
call someotherfunction
${ELSE}
goto fail
${ENDIF}
FileClose $chk
Delete $chk
fail:
MessageBox MB_OK|MB_ICONSTOP "fail"
//Here this call is not working
${NSD_OnBack} "callbackfunction"
SectionEnd
Function callbackfunction
GetDlgItem $0 $HWNDPARENT 2
${IF} $portalname == "centralised"
${IF} $username == ""
call CentralisedPage
${ENDIF}
${ELSE}
${IF} $username == ""
call SetCustom
${ENDIF}
${ENDIF}
Functionend
I am expecting to move other page based on EXE results.
${NSD_OnBack} is a callback for nsDialogs custom pages and it is invoked when the user presses the back button on that page, it is not relevant here.
Ideally you should collect all information before you get to the InstFiles page but if you can't do that then I would recommend that you just show a custom page after the InstFiles page if required.
If you absolutely need to execute sections multiple times you can use more than one InstFiles page:
!include LogicLib.nsh
!include WinMessages.nsh
!include nsDialogs.nsh
!include Sections.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init1stStage
!insertmacro MUI_PAGE_INSTFILES
Page Custom MyCustomPageCreate
!define MUI_PAGE_CUSTOMFUNCTION_PRE Init2ndStage
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Var Needs2ndStage
Section "1st stage" SID_1
DetailPrint "1st stage"
MessageBox mb_yesno "Needs 2nd stage?" IDNO nope
StrCpy $Needs2ndStage 1
nope:
SectionEnd
Section "-2nd stage" SID_2
DetailPrint "2nd stage"
SectionEnd
Function Init1stStage
!insertmacro UnselectSection ${SID_2}
FunctionEnd
Function Init2ndStage
!insertmacro UnselectSection ${SID_1}
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
FunctionEnd
Function MyCustomPageCreate
${IfThen} $Needs2ndStage = 0 ${|} Abort ${|}
!insertmacro SelectSection ${SID_2}
GetDlgItem $0 $hWndParent 1
SendMessage $0 ${WM_SETTEXT} "" "STR:C&ontinue"
GetDlgItem $0 $hWndParent 3
ShowWindow $0 0 ; Hide back
GetDlgItem $0 $hWndParent 2
EnableWindow $0 0 ; Disable cancel
!insertmacro MUI_HEADER_TEXT "Blah" "Blah blah blah"
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 0 100% 12u "Enter blah blah before you can enter the 2nd stage"
Pop $0
nsDialogs::Show
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 script + Skip button alignment issue

I am trying NSIS script to add "SKIP" button.
I have tested below code and it works well but when I actually integrate with the main code which is having a screen of option "back" "Next" and "Cancel" button. this skip button is not visible at all, it is in extreme right of cancel button and hardly visible.
How can move this "Skip" button towards left side.
Name BtnTest
Outfile test.exe
Installdir "$temp"
RequestExecutionLevel user
BrandingText " " ;Button covers this text
!include nsDialogs.nsh ;For WS_*
!define MUI_CUSTOMFUNCTION_GUIINIT SKIP
Function SKIP
; You are supposed to use ChangeUI (or MUI_UI) and a modified ui file to add new buttons but this example adds the button at run-time...
GetDlgItem $0 $hwndparent 2 ; Find cancel button
System::Call *(i,i,i,i)i.r1
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(i$hwndparent,ir1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
IntOp $2 $2 + $4 ;x
IntOp $2 $2 + 8 ;x+padding
System::Call 'USER32::CreateWindowEx(i0,t "Button",t "Click Me",i${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},ir2,ir3,ir4,ir5,i $hwndparent,i 0x666,i0,i0)i.r0'
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $0 onmybtnclick
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function onmybtnclick
MessageBox mb_ok "You clicked me!"
FunctionEnd
Page Directory
Page Instfiles
Section
SectionEnd
And also this button appears on all screen How can I display only in one screen.
Change $2 and $3 before the call to CreateWindowEx to change the button position. You can save the handle to the button in another variable after CreateWindowEx but I just used the Id in this example (0x666).
Name BtnTest
Outfile test.exe
Installdir "$temp"
RequestExecutionLevel user
BrandingText " " ;Button covers this text
!include nsDialogs.nsh ;For WS_*
!define MUI_CUSTOMFUNCTION_GUIINIT SKIP
/**/ !include MUI2.nsh #*/
!ifndef MUI_INCLUDED
Function .onGuiInit
Call SKIP
FunctionEnd
!endif
Function SKIP
; You are supposed to use ChangeUI (or MUI_UI) and a modified ui file to add new buttons but this example adds the button at run-time...
GetDlgItem $0 $hwndparent 2 ; Find cancel button
System::Call *(i,i,i,i)i.r1
System::Call 'USER32::GetWindowRect(ir0,ir1)'
System::Call *$1(i.r2,i.r3,i.r4,i.r5)
IntOp $5 $5 - $3 ;height
IntOp $4 $4 - $2 ;width
System::Call 'USER32::ScreenToClient(i$hwndparent,ir1)'
System::Call *$1(i.r2,i.r3)
System::Free $1
!ifdef MUI_INCLUDED
StrCpy $2 15 ; Whatever you feel looks good
!else
IntOp $2 $2 + $4 ;x
IntOp $2 $2 + 8 ;x+padding
!endif
System::Call 'USER32::CreateWindowEx(i0,t "Button",t "Click Me",i${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},ir2,ir3,ir4,ir5,i $hwndparent,i 0x666,i0,i0)i.r0'
SendMessage $hwndparent ${WM_GETFONT} 0 0 $1
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $0 onmybtnclick
ButtonEvent::AddEventHandler 0x666 $0
FunctionEnd
Function onmybtnclick
MessageBox mb_ok "You clicked me!"
FunctionEnd
Function HideIt
GetDlgItem $0 $hwndparent 0x666
ShowWindow $0 0
FunctionEnd
Function ShowIt
GetDlgItem $0 $hwndparent 0x666
ShowWindow $0 1
FunctionEnd
!ifdef MUI_INCLUDED
!define MUI_PAGE_CUSTOMFUNCTION_SHOW HideIt
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_SHOW ShowIt
!insertmacro MUI_PAGE_COMPONENTS
!define MUI_PAGE_CUSTOMFUNCTION_SHOW HideIt
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
!else
Page Components "" HideIt
Page Components "" ShowIt
Page Components "" HideIt
Page Instfiles
!endif
Section
SectionEnd

Resources