Search code examples
nsis

How to conditionally set first InstType in Component page


I want to conditionally set the first Installation type in Component page based on checking if some files already exists on the machine.

I've already tried two different approachs. 1) using SetCurInstType, 2) conditionally defining the InstType sequence order on the basis of a "file exist" check.

Both the approaches have been tested using an UDF function. This UDF function has been used, alternatively, as input for the MUI_PAGE_CUSTOMFUNCTION_LEAVE of MUI_PAGE_LICENSE and for the MUI_PAGE_CUSTOMFUNCTION_PRE of MUI_PAGE_COMPONENTS.

Both tests didn't work as expected

Approach 1)

InstType "Install (all)"
InstType "Install (minimal)"
    !define USER_ALL_INST_TYPE 1
    !define USER_MIN_INST_TYPE 2

!define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
    !insertmacro MUI_PAGE_COMPONENTS

Section "1" Sec1 
    SectionIn ${USER_ALL_INST_TYPE} ${USER_MIN_INST_TYPE}

    ... other code

SectionEnd

Section "2" Sec2 
    SectionIn ${USER_ALL_INST_TYPE}

    ... other code

SectionEnd

Function SetInitInstType
    IfFileExists "<file_path>" 0 endSetInitInstType
    SetCurInstType ${USER_MIN_INST_TYPE}

    endSetInitInstType:
FunctionEnd

Approach 2)

!define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
    !insertmacro MUI_PAGE_COMPONENTS

Section "1" Sec1 
    SectionIn ${USER_ALL_INST_TYPE} ${USER_MIN_INST_TYPE}

    ... other code

SectionEnd

Section "2" Sec2 
    SectionIn ${USER_ALL_INST_TYPE}

    ... other code

SectionEnd

Function SetInitInstType
    IfFileExists "<file_path>" 0 SetAllInstType
    InstType "Install (minimal)"
    InstType "Install (all)"
        !define USER_MIN_INST_TYPE 1
        !define USER_ALL_INST_TYPE 2

    Goto endSetInitInstType

    SetAllInstType:
    InstType "Install (all)"
    InstType "Install (minimal)"
        !define USER_ALL_INST_TYPE 1
        !define USER_MIN_INST_TYPE 2

    endSetInitInstType:
FunctionEnd

After Condition check, if file existed, the expected result would be that the Install Mode ComboBox in Component page was initialized with the "Install (minimal)" option

The actual result is instead as follow:

Approach 1) --> All sections are disabled and the Install Mode ComboBox is initialized with the "Custom" option

Approach 2) --> I receive an error during script compiling

Section: "1" ->(Sec1)
SectionIn: Usage: SectionIn InstTypeIdx [InstTypeIdx [...]]
Error in script "<script_name>.nsi" on line XXX -- aborting creation process

Any suggestion would be really appreciated


Solution

  • Don't ask me why but SectionIn uses a different index system than all the other inst type functions.

    Unlike SectionIn the index is zero based, which means the first install type's index is 0

    !include MUI2.nsh
    
    !define MUI_PAGE_CUSTOMFUNCTION_PRE SetInitInstType
    !insertmacro MUI_PAGE_COMPONENTS
    !insertmacro MUI_PAGE_DIRECTORY
    !insertmacro MUI_PAGE_INSTFILES
    !insertmacro MUI_PAGE_FINISH
    !insertmacro MUI_LANGUAGE "English"
    
    !macro AddInstType name text
    !define /IfNDef AddInstType_COUNTER 0
    InstType "${text}"
    !define INSTTYPE_${name}_IDX ${AddInstType_COUNTER} ; For SetCurInstType etc.
    !define /ReDef /Math AddInstType_COUNTER ${AddInstType_COUNTER} + 1
    !define INSTTYPE_${name}_SIN ${AddInstType_COUNTER} ; For SectionIn
    !macroend
    
    !insertmacro AddInstType ALL "Install (all)"
    !insertmacro AddInstType MIN "Install (minimal)"
    
    Section "1 (Both)" Sec1 
    SectionIn ${INSTTYPE_ALL_SIN} ${INSTTYPE_MIN_SIN}
    SectionEnd
    
    Section "2 (All only)" Sec2 
    SectionIn ${INSTTYPE_ALL_SIN}
    SectionEnd
    
    Function SetInitInstType
        IfFileExists "$WinDir\Explorer.exe" 0 +2
            SetCurInstType ${INSTTYPE_MIN_IDX}
    FunctionEnd
    
    Function .onInit
        Call SetInitInstType ; In case installer is silent, force correct sections
    FunctionEnd