nsisnsdialogs

Conditional Installation with NSIS


I need to make an installer that will also act as a repair/uninstall program if the concerned software is already installed.

I managed to make a custom page that check if the program exists and display buttons depending on that (the registry key creation is only for testing purpose and should be included in installation process).

For example, an Install button appears if the program isn't installed.

Here is the code doing this :

Page Custom MyCustomPage

var button
var buttonRepair
var buttonUninstall
var dialog

Function MyCustomPage
ReadRegStr $R0 HKLM ${P_DIR_REGKEY} "Version"
${If} ${Errors}
    Goto NotInstalled
${Else}
    Goto Installed
${EndIf}

    NotInstalled:
        nsDialogs::Create 1018
        ;Pop $dialog
        ${NSD_CreateButton} 25% 25% 50% 50% "Install"
        Pop $button
        EnableWindow $button 1 # start out disabled
        WriteRegStr HKLM ${P_DIR_REGKEY} "Version" ${P_VERSION}
        WriteRegStr HKLM ${P_DIR_REGKEY} "" "$INSTDIR\asd.exe"
        nsDialogs::Show
        ${NSD_OnClick} $button ManageInstall
        Goto MyEnd
    Installed:
        nsDialogs::Create 1018
        Pop $0
        ${NSD_CreateButton} 12% 12% 25% 25% "Repair"
        Pop $buttonRepair
        ${NSD_CreateButton} 37% 12% 25% 25% "Uninstall"
        Pop $buttonUninstall
        EnableWindow $button 1 # start out disabled
        EnableWindow $button2 1
        ${NSD_OnClick} $buttonRepair ManageRepair
        ${NSD_OnClick} $buttonUninstall ManageUninstall
        nsDialogs::Show
        Goto MyEnd
    MyEnd:
        Quit
FunctionEnd

Function ManageInstall
    MessageBox MB_OK "Installation"
FunctionEnd

Function ManageRepair
    MessageBox MB_OK "Repair"
FunctionEnd

Function ManageUninstall
    MessageBox MB_OK "Uninstallation"
FunctionEnd

The problem is that it's all managed by functions, and I can't declare new pages macros in them, so I can't continue with the proper installation through sections because of it.

How should I manage the different actions to be taken by the installer to be able to make user friendly pages like a normal install ?

Should I use custom pages for every single action, because it sounds a bit fastidious and complicated ?


Solution

  • I recommend you create a variable named "ACTION", and set its value when the user clicks an option. And then, jump to the next page. Something like this:

    # http://nsis.sourceforge.net/Go_to_a_NSIS_page
    Function RelGotoPage
      IntCmp $R9 0 0 Move Move
        StrCmp $R9 "X" 0 Move
          StrCpy $R9 "120"
    
      Move:
      SendMessage $HWNDPARENT "0x408" "$R9" ""
    FunctionEnd
    
    Function GotoNextPage
        StrCpy $R9 "1"
        Call RelGotoPage
    FunctionEnd
    
    
    Function ManageRepair
        StrCpy $ACTION "repair"
        Call GotoNextPage
        Abort
    FunctionEnd
    

    Then, on each page's "pre" function, you need to check it it has to be displayed or not:

    Function repairpage
        # Do not display this page unless user selected Repair.
        ${if} "$ACTION" != "repair"
            Abort
        $[EndIf}
    
        ....
    FunctionEnd