Search code examples
nsis

How to set the checkbox by default checked in the windows installer Finish page using NSIS


I wanted to set the checkbox as checked by default in the windows installer Finish page using NSIS. For that I used the below code snipped. But it is not even displaying the checkbox in the Finish page. Please help me on this.

Var Checkbox
Var CheckState ; Stored globally so we remember the choice if the user presses the back button and goes back to our page
!define CheckHeight 28
!macro CreateNativeControl hParent cls style exstyle x y w h text ; Note: Only supports pixel coordinates
System::Call 'USER32::CreateWindowEx(i ${exstyle}, t "${cls}", ts, i ${style}, i ${x}, i ${y}, i ${w}, i ${h}, p ${hParent}, i0, i0, i0)p.s' "${text}"
!macroend

 !define MUI_PAGE_CUSTOMFUNCTION_SHOW FinishShow
 !insertmacro MUI_PAGE_FINISH

Function FinishShow

  System::Call *(i,i,i,i)p.r0 ; NSIS 2.51+
  System::Call 'USER32::GetWindowRect(p$mui.FinishPage.Text, pr0)'
  System::Call 'USER32::MapWindowPoints(i0,p$mui.FinishPage,p$0,i2)'
  System::Call '*$0(i.r2,i.r3,i.r4,i.r5)'
  System::Free $0
  IntOp $5 $5 - ${CheckHeight}
  System::Call 'USER32::SetWindowPos(i$mui.FinishPage.Text,i,i,i,i$4,i$5,i0x6)'
  
  ; Create and initialize the checkbox
  IntOp $5 $3 + $5 ; y = TextTop + TextHeight
  !insertmacro CreateNativeControl $mui.FinishPage ${__NSD_CheckBox_CLASS} "${__NSD_CheckBox_STYLE}" "${__NSD_CheckBox_EXSTYLE}" 0 $5 300 ${CheckHeight} "CheckboxTest"
  Pop $Checkbox
  SendMessage $mui.FinishPage ${WM_GETFONT} 0 0 $0 
  SendMessage $Checkbox ${WM_SETFONT} $0 1 
  System::Call 'USER32::SetWindowPos(i$Checkbox,i0,i,i,i,i,i0x33)' 
  ${IfThen} $CheckState == "" ${|} StrCpy $CheckState 1 ${|} 
  ${NSD_SetState} $Checkbox $CheckState
FunctionEnd

Solution

  • The finish page has built-in support for two optional check-boxes:

    !include MUI2.nsh
    !insertmacro MUI_PAGE_WELCOME
    !insertmacro MUI_PAGE_INSTFILES
    !define MUI_FINISHPAGE_RUN ""
    !define MUI_FINISHPAGE_RUN_TEXT "Run Foo"
    !define MUI_FINISHPAGE_RUN_FUNCTION MyRunFoo
    ;define MUI_FINISHPAGE_RUN_NOTCHECKED
    !define MUI_FINISHPAGE_SHOWREADME "$InstDir\Bar.exe"
    !define MUI_FINISHPAGE_SHOWREADME_TEXT "Run Bar"
    ;define MUI_FINISHPAGE_SHOWREADME_FUNCTION
    !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
    !insertmacro MUI_PAGE_FINISH
    !insertmacro MUI_LANGUAGE English
    
    Function MyRunFoo
    ; Exec '"$InstDir\Foo.exe"'
    FunctionEnd
    
    Section
    SectionEnd
    

    Your example code is also missing a important call to !insertmacro MUI_LANGUAGE.

    The function specified by MUI_FINISHPAGE_RUN_FUNCTION is only executed if the checkbox is checked. This is normal expected behavior.

    If you want to do custom handling you can do it in the leave page:

    !include nsDialogs.nsh
    !include LogicLib.nsh
    !include MUI2.nsh
    !insertmacro MUI_PAGE_WELCOME
    !insertmacro MUI_PAGE_INSTFILES
    !define MUI_FINISHPAGE_RUN "" 
    !define MUI_FINISHPAGE_RUN_TEXT "Blah blah" 
    !define MUI_PAGE_CUSTOMFUNCTION_LEAVE FinishLeave 
    !insertmacro MUI_PAGE_FINISH
    !insertmacro MUI_LANGUAGE English
    
    Function FinishLeave 
    ${NSD_GetState} $mui.FinishPage.Run $0 ; or $mui.FinishPage.ShowReadme
    ${If} $0 <> 0 
    MessageBox mb_ok "Checkbox checked"
    ${Else} 
    MessageBox mb_ok "Checkbox not checked" 
    ${EndIf}
    FunctionEnd