Customizing an exsisting NSIS MUI2 page using nsDialogs - nsis

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
...

Related

How to use nsdialogs REMOVE or REPAIR feature in NSIS script?

My installer working fine without nsdialogs, If i add nsdialogs its not working good.I can't call nsdialogs in correct place.where i need to call nsdialogs?
Var hwnd
Var Dialog
Page custom checkinstall
Page custom nsDialogsPage
.
.
.
Function .onInit
!define MUI_LANGDLL_ALWAYSSHOW
!insertmacro MUI_LANGDLL_DISPLAY
SetShellVarContext all
!insertmacro VerifyUserIsAdmin
FunctionEnd
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
SetShellVarContext all
SetRebootFlag true
MessageBox MB_OKCANCEL "Are you sure you want to uninstall
${APPNAME}?" IDOK next
Abort
next:
!insertmacro VerifyUserIsAdmin
FunctionEnd
Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed
from your computer."
FunctionEnd
Function Repair
Call .onInit
FunctionEnd
Function Remove
ExecWait "$INSTDIR\Uninstall.exe"
FunctionEnd
Function checkinstall
ReadRegStr $R0 HKLM \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"UninstallString"
IfFileExists $R0 +1 NotInstalled
Call nsDialogsPage
NotInstalled:
FunctionEnd
Function nsDialogsPage
nsDialogs::Create 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
${NSD_CreateRadioButton} 0 5u 100% 10u "Repair"
Pop $hwnd
${NSD_AddStyle} $hwnd ${WS_GROUP}
${NSD_OnClick} $hwnd Repair
${NSD_CreateRadioButton} 0 25u 100% 56u "Remove"
Pop $hwnd
${NSD_OnClick} $hwnd Remove
nsDialogs::Show
FunctionEnd
I can not call nsdialogs correctly. checkinstall function not working at all.I need a correct solution for that.
You are writing the uninstall command to the registry with quotes (correct) but you are not removing the quotes when reading the value so the file exists test is always going to be false.
You should remove the quotes from commands you read from the registry:
Function GetAppFromCommand
Exch $1
Push $2
Push $3
StrCpy $3 ""
StrCpy $2 $1 1
StrCmp $2 '"' qloop sloop
sloop:
StrCpy $2 $1 1 $3
IntOp $3 $3 + 1
StrCmp $2 "" +2
StrCmp $2 ' ' 0 sloop
IntOp $3 $3 - 1
Goto done
qloop:
StrCmp $3 "" 0 +2
StrCpy $1 $1 "" 1 ; Remove initial quote
IntOp $3 $3 + 1
StrCpy $2 $1 1 $3
StrCmp $2 "" +2
StrCmp $2 '"' 0 qloop
done:
StrCpy $1 $1 $3
Pop $3
Pop $2
Exch $1
FunctionEnd
!macro GetAppFromCommand cmd outvar
Push `${cmd}`
Call GetAppFromCommand
Pop ${outvar}
!macroend
Function checkinstall
ReadRegStr $R0 HKLM \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
"UninstallString"
!insertmacro GetAppFromCommand $R0 $R0
IfFileExists $R0 +1 NotInstalled
Call nsDialogsPage
NotInstalled:
FunctionEnd

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

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

NSIS WndSubClass error

I want to study about WndSubClass Plugin
So I compiled WndSubClass Example Source
But It was errored with message
NSIS v2.42 and later required!
But I'm Using NSIS Lastest Version(3.0rc1)
What Should I do?
Code
!AddPluginDir ".\release\"
!include WndSubclass.nsh
!include WinMessages.nsh
!include LogicLib.nsh
!define N "WndSubclassExample"
Name ${N}
OutFile "$%temp%\${N}.exe"
ShowInstDetails show
LicenseText "<<< hover over the icon, or click it$\n>>> or move this window with the minimize button!!!"
Caption "${N}"
SubCaption 0 " "
page license "" licshow
var MainWndSubProc
var IconSubProc
var hLic
var IconAnim
var firstbrandscroll
Function .onInit
!if 0
FindWindow $0 dbgviewClass
SendMessage $0 ${WM_COMMAND} 40020 0
System::Call user32::SetForegroundWindow(i$0)
!endif
FunctionEnd
Function IconSubProc
#System::Call 'kernel32::OutputDebugString(t "IconSubProc: $1 $2 $3 $4 $\n")'
${If} $2 = ${WM_NCHITTEST}
${If} $IconAnim = 0
System::Call 'user32::SetTimer(i $HWNDPARENT,i 1,i 50,i0)'
StrCpy $IconAnim 1
System::Call 'user32::SetTimer(i $1,i 1,i 50,i0)'
${EndIf}
${WndSubClass_Ret} 1
${ElseIf} $2 = ${WM_TIMER}
System::Call *(i,i,i,i)i.r0
System::Call user32::GetWindowRect(i$1,i$0)
FindWindow $2 "#32770" "" $HWNDPARENT
System::Call 'user32::MapWindowPoints(i 0,i $2,i $0,i 2)'
System::Call '*$0(i.r5,i.r6)'
IntOp $IconAnim $IconAnim + 1
IntOp $9 $IconAnim % 2
${If} $9 = 1
IntOp $6 $6 + 2
${Else}
IntOp $6 $6 - 2
${EndIf}
${If} $IconAnim > 10
System::Call user32::KillTimer(i$1,i1)
call ResetLicTick
StrCpy $IconAnim 0
${EndIf}
System::Call 'user32::SetWindowPos(i $1,i 0,i $5,i $6,i0,i0,i 1)'
System::Free $0
${ElseIf} $2 = ${WM_LBUTTONUP}
${If} $hLic = 0
quit
${EndIf}
call ResetLicTick
StrCpy $0 $hLic
StrCpy $hLic 0
SendMessage $0 ${WM_SETTEXT} 0 "STR:You disabled the ticker, don't click the icon again"
${EndIf}
FunctionEnd
Function MainWndSubProc
#System::Call 'kernel32::OutputDebugString(t "MainWndSubProc: $1 $2 $3 $4 $\n")'
${If} $2 = ${WM_NCHITTEST}
${WndSubClass_CallNextWndProc} $MainWndSubProc "" "" "" "" ;result in $0
${IfThen} $0 = 8 ${|} StrCpy $0 2 ${|} ;take over minimize btn and fake as HTCAPTION
${WndSubClass_Ret} $0
${ElseIf} $2 = ${WM_TIMER}
${If} $3 == 1
System::Call kernel32::GetTickCount()i.r0
SendMessage $hLic ${WM_SETTEXT} 0 "STR:Tick=$0"
${ElseIf} $3 == 2
GetDlgItem $0 $HWNDPARENT 0x404
System::Call 'user32::SendMessage(i $0,i ${WM_GETTEXT},i 99,t.r1)'
${If} $firstbrandscroll != 1
StrCpy $firstbrandscroll 1
StrCpy $1 "$1... "
${EndIf}
StrCpy $2 $1 1
StrCpy $1 "$1$2" "" 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:$1"
${EndIf}
${EndIf}
FunctionEnd
Function ResetLicTick
System::Call user32::KillTimer(i$HWNDPARENT,i1)
SendMessage $hLic ${WM_SETTEXT} 0 "STR:Tick=?"
FunctionEnd
Function licshow
${WndSubclass_Subclass} $HWNDPARENT MainWndSubProc $MainWndSubProc $MainWndSubProc
CreateFont $9 Arial 22
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $hLic $0 1000
GetDlgItem $1 $0 0x407
${WndSubclass_Subclass} $1 IconSubProc $IconSubProc $IconSubProc
SendMessage $hLic ${WM_SETFONT} $9 0
call ResetLicTick
System::Call 'user32::SetTimer(i $HWNDPARENT,i 2,i 250,i0)'
FunctionEnd
Section
SectionEnd
If you just Google "NSIS v2.42 and later required!" the first result should be this forum thread and it says you can fix it by adding this to the top of your .nsi:
!if "${NSIS_CHAR_SIZE}" = 1
!define __WNDSUBCLASS_NSISVEROK
!endif
!include "WndSubclass.nsh"

SelectFolderDialog with only drives, no folder selection inside drives

In nsis SelectFolderDialog for folder selection window. But i want to appear or user to select only drives.There should not be selection of folders inside a drive.
So user should get drives like C: D: E: etc
Is there any option to do it?
This only allows you to select paths shorter than 4 characters inside My Computer, if you want to hide the folders in the dialog you need to write a plugin and implement IFolderFilter (WinXP+ only)
#BIF_RETURNONLYFSDIRS 0x00000001
#BIF_NEWDIALOGSTYLE 0x00000040
#BIF_NONEWFOLDERBUTTON 0x00000200
!include LogicLib.nsh
!include WinMessages.nsh
!define /math BFFM_ENABLEOK ${WM_USER} + 101
!define BFFM_SELCHANGED 2
System::Call 'SHELL32::SHGetSpecialFolderLocation(i0,i0x11,*i.r2)i.r0'
System::Get "(i.R0,i.R1,i.R2,i)iR9R9"
Pop $3
System::Call '*(i$hwndparent,i$2,i,t "Hello",i0x241,kr3,i0,i0)i.r1'
System::Call 'SHELL32::SHBrowseForFolder(ir1)i.r0'
Sys_BFFCALLBACK:
${If} $R9 == "callback1"
${If} ${BFFM_SELCHANGED} = $R1
System::Call 'SHELL32::SHGetPathFromIDList(i$R2,t "" R9)'
StrLen $R9 $R9
${IfThen} $R9 > 3 ${|} StrCpy $R9 0 ${|}
SendMessage $R0 ${BFFM_ENABLEOK} 0 $R9
${EndIf}
StrCpy $R9 0 ; return value
System::Call $3
Goto Sys_BFFCALLBACK
${EndIf}
System::Free $3 ; system callback
System::Call 'OLE32::CoTaskMemFree(ir2)' ; BROWSEINFO.pidlRoot
System::Free $1 ; BROWSEINFO
${If} $0 <> 0
System::Call 'SHELL32::SHGetPathFromIDList(i$0,t "" R9)'
MessageBox mb_ok SHBrowseForFolder=$R9
${EndIf}
System::Call 'OLE32::CoTaskMemFree(ir0)' ; pidl result

Determine on nsis if internet connection is available

How can I determine if is there available internet connection on my NSIS function?
I saw Intec plugin but I didn't find how to do that
Thanks.
You should use Dailer plugin for that.
Try this:
Dialer::GetConnectedState
Pop $1
if there is internet connection, $1 will be online either, it will be offline
Read more on:
http://nsis.sourceforge.net/Docs/Dialer/Dialer.txt
According to NSIS documentation on Windows Vista and later it is recommended to use INetworkListManager::GetConnectivity() to check if Internet is connected.
Here is a function that uses recommended approach:
!include "LogicLib.nsh"
Function IsInternetConnected
!define CLSID_NetworkListManager "{DCB00C01-570F-4A9B-8D69-199FDBA5723B}"
!define IID_INetworkListManager "{DCB00000-570F-4A9B-8D69-199FDBA5723B}"
!define CLSCTX_ALL 23
Push $R0
Push $R1
Push $R2
Push $R3
Push $R9
; Result - is internet connected.
StrCpy $R0 false
SetPluginUnload alwaysoff
System::Call "ole32::CoCreateInstance(g '${CLSID_NetworkListManager}', i 0, i ${CLSCTX_ALL}, g '${IID_INetworkListManager}', *i .R1) i .R9"
IntCmp $R9 0 0 end
; INetworkListManager->GetConnectivity(NLM_CONNECTIVITY*)
System::Call "$R1->13(*i .R2) i .R9"
IntCmp $R9 0 0 end
; IUnknown->Release()
System::Call "$R1->2() i"
; Internet IPv4: NLM_CONNECTIVITY_IPV4_INTERNET = 64.
IntOp $R3 $R2 & 64
${If} $R3 <> 0
StrCpy $R0 true
Goto end
${EndIf}
; Internet IPv6: NLM_CONNECTIVITY_IPV6_INTERNET = 1024.
IntOp $R3 $R2 & 1024
${If} $R3 <> 0
StrCpy $R0 true
Goto end
${EndIf}
end:
SetPluginUnload manual
Pop $R9
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
This is how to use this function:
!include "LogicLib.nsh"
Section
Push $0
Call IsInternetConnected
Pop $0
${If} $0 == false
MessageBox MB_OK "Internet is not connected"
${Else}
MessageBox MB_OK "Internet is connected"
${EndIf}
Pop $0
SectionEnd
May be it will be useful for somebody.
TESTAGIN:
ClearErrors
SetDetailsPrint both
DetailPrint "$(TEST_TEST)"
SetDetailsPrint none
inetc::head /silent "http://www.msn.com" "$SYSDIR\test.txt"
Pop $0 # return value = exit code, "OK" if OK
${If} $0 != OK
GOTO Done
${Else}
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(TEST_INTERNET_CONNECTION)" IDRETRY TESTAGIN
#quit
${EndIf}
Done:
SetDetailsPrint both
DetailPrint "$(TEST_OK)"
SetDetailsPrint none
ClearErrors

Resources