Search code examples
nsis

NSIS - Conditionally Display Components


I want the installer/uninstaller to check if any of the possible components are installed, and display only relevan components (installer should display only components not already installed and uninstaller should display only already-installed components)

I'm using MUI.

The component section of my .nsi looks something like this:

; Section descriptions
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${Component1} "Component1 Description"
    !insertmacro MUI_DESCRIPTION_TEXT ${Component2} "Component2 Description."
    !insertmacro MUI_DESCRIPTION_TEXT ${Component3} "Component3 Description."
!insertmacro MUI_FUNCTION_DESCRIPTION_END

I've tried a couple of different ways:

First, I tried using this macro for checking if a registry exists:

!insertmacro IfKeyExists HKEY_LOCAL_MACHINE SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall "Component1"
Pop $R0
${If} $R0 == 0 #Not installed yet. Display.
    !insertmacro MUI_DESCRIPTION_TEXT ${Component1} "Component1"
${EndIf}

This didn't work.

Then I tried using the Registry Plug-In:

${registry::KeyExists} "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Component1" $R0
${If} $R0 == 0 #Not installed yet. Display.
    !insertmacro MUI_DESCRIPTION_TEXT ${Component1} "Component1"
${EndIf}

This didn't work either.

So then I thought maybe there was some other more basic problem, and I tried this:

StrCpy $0 "0"
${If} $0 == "1"
    !insertmacro MUI_DESCRIPTION_TEXT ${Component1} "Component1 Description."
${EndIf}

But even then I still saw "Component1" as a possible component during installation!

What am I doing wrong and how can I go about achieving my goal?

Thanks in advance!


Solution

  • To select a section (= a component) at runtime you can use SectionGetFlag / SectionSetFlag and some bit manipulation :

    SectionGetFlags ${test_section_id} $0
    IntOp $0 $0 | ${SF_SELECTED}
    SectionSetFlags ${test_section_id} $0
    

    To deselect it, just toogle its selected bit, with

    SectionGetFlags ${test_section_id} $0
    IntOp $0 $0 ^ ${SF_SELECTED}
    SectionSetFlags ${test_section_id} $0
    

    These are simpler if you include the Sections.nsh header and use the SelectSection and UnselectSection macros.

    If you want to hide a section, you just need to set its text to "" (empty string)

    SectionSetText ${test_section_id} ""