Controlling Available Install Options

From NSIS Wiki
Jump to navigationJump to search
Author: KiCHiK (talk, contrib)


Description

InstallOptions1Required4Optional.png

I wrote this script in answer to the following question on the forum by user Sailo:

I have 5 install options 1 is required and the other 4 are optional. The only problem is i want the user to only be able to select 1 of the 4 options so that when you check 1 box the check disappears from 1 of the other options. Is this possible?

The Script

Here's the script for NSIS 2.0a0 up to 2.0b0 that solves the problem. If you are using version 2.0b0 and above use Examples\one-section.nsi. This script can work on version 1.98 too. All you need to do is remove "SectionIn RO", sec1, sec2, sec3, and sec4, and replace every ${sec*} with the appropriate section number.

# This example demonstrates how to control section selection.
# It allows only one of the four optional section to be
# selected at any given time.
#
# Please note that the initial value will not be what you expect
# it to be if you are are using InstType because InstType is taken
# into consideration after the .onInit, where the initial state is
# set, executes.
# To use this code with InstType you will either have to specify
# you first InstType to match the initial value you set in .onInit
# (only StrCpy $1 ${sec1} is important in this case because the
# other set the section and that will be done by InstType), or set
# the initial section selection from .onSelChange when it is called
# for the first time.
 
Name example
OutFile setup.exe
 
ComponentText "please choose just one but the default"
 
Section !Required
  SectionIn RO
SectionEnd
 
Section "optional #1" sec1
SectionEnd
 
Section "optional #2" sec2
SectionEnd
 
Section "optional #3" sec3
SectionEnd
 
Section "optional #4" sec4
SectionEnd
 
# defines for newer versions
!include Sections.nsh
# SECTION_OFF is defined in Sections.nsh as 0xFFFFFFFE
!define SECTION_ON ${SF_SELECTED} # 0x1
 
# defines for 2.0b0 and below
#!define SECTION_ON 0x80000000
#!define SECTION_OFF 0x7FFFFFFF
 
Function .onInit
  Push $0
 
  StrCpy $1 ${sec1} ; Gotta remember which section we are at now...
  SectionGetFlags ${sec1} $0
  IntOp $0 $0 | ${SECTION_ON}
  SectionSetFlags ${sec1} $0
 
  SectionGetFlags ${sec2} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec2} $0
 
  SectionGetFlags ${sec3} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec3} $0
 
  SectionGetFlags ${sec4} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec4} $0
 
  Pop $0
FunctionEnd
 
Function .onSelChange
  Push $0
 
  ; Turn off old selected section
  SectionGetFlags $1 $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags $1 $0
 
  ; Now remember the current selection
  Push $2
  StrCpy $2 $1
 
  SectionGetFlags ${sec1} $0
  IntOp $0 $0 & ${SECTION_ON}
  IntCmp $0 ${SECTION_ON} 0 +2 +2
    StrCpy $1 ${sec1}
  SectionGetFlags ${sec2} $0
  IntOp $0 $0 & ${SECTION_ON}
  IntCmp $0 ${SECTION_ON} 0 +2 +2
    StrCpy $1 ${sec2}
  SectionGetFlags ${sec3} $0
  IntOp $0 $0 & ${SECTION_ON}
  IntCmp $0 ${SECTION_ON} 0 +2 +2
    StrCpy $1 ${sec3}
  SectionGetFlags ${sec4} $0
  IntOp $0 $0 & ${SECTION_ON}
  IntCmp $0 ${SECTION_ON} 0 +2 +2
    StrCpy $1 ${sec4}
 
  StrCmp $2 $1 0 +4 ; selection hasn't changed
    SectionGetFlags $1 $0
    IntOp $0 $0 | ${SECTION_ON}
    SectionSetFlags $1 $0
  Pop $2
  Pop $0
FunctionEnd