Search code examples
loggingheadernsisuninstallation

nsis Advanced Uninstall Log - uninstaller needs to reside in a different dir


Requirement 1: It is required that our uninstaller remove only files in a specific folder installed by the installer (i.e. any files added after install must remain intact).

Requirement 2: It is also required that the uninstaller reside in a specific location other than the above mentioned folder.

I found and have experimented with the "Advanced Uninstall Log NSIS Header" found here : http://nsis.sourceforge.net/Advanced_Uninstall_Log_NSIS_Header

While the Advanced Uninstall Log NSIS Header looks very promising, (meets requirement 1 quite well), I am unable to determine if I can make it also work with Requirement 2.

Can the header be used to uninstall only installed files AND be invoked from a different dir other than the dir in which the .dat file is created?

Thanks in advance.


Solution

  • In AdvUninstLog.nsh you should comment out anything related to UNINST_EXE, especially the WriteUninstaller line. I was not sure if you wanted the .dat and the uninstaller in the same directory so I used separate directories just to be on the safe side.

    ...
    !include AdvUninstLog.nsh
    !insertmacro UNATTENDED_UNINSTALL
    Page Directory 
    Page InstFiles
    
    Function .onInit
    
        !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
    
    FunctionEnd
    
    
    Function .onInstSuccess
    
        !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
    
    FunctionEnd
    
    Section "Main Application"
    
        SetOutPath "$InstDir\foo"
        WriteUninstaller "$InstDir\foo\uninst.exe"
    
        SetOutPath "$InstDir\data"
        !insertmacro UNINSTALL.LOG_OPEN_INSTALL
        File /r "${NSISDIR}\Plugins\*" ; "random" files
        !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
    
        WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "InstallDir" "$InstDir"
        WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "DisplayName" "${APP_NAME}"
        WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "UninstallString" '"$InstDir\foo\uninst.exe"'
    
        ; Because the UNINSTALL.LOG_UPDATE_INSTALL macro is responsible for writing the .dat
        ; it is important to set $InstDir to the directory you want it to be located in.
        ; This must be done as the last step in your last Section so that $InstDir has
        ; the correct path when .onInstSuccess is executed.
        SetOutPath "$InstDir\bar" ; Make sure the directory exists
        StrCpy $InstDir "$InstDir\bar"
    
    SectionEnd
    
    Section UnInstall
    
        ; In the uninstaller the initial value of $InstDir is the folder the uninstaller .exe is in.
        ; In this example I put it in a subfolder so we need to get the root of our install:
        GetFullPathname $InstDir "$InstDir\..\"
    
        ; This is important, it changes $InstDir to the folder where the .dat is located.
        Push $InstDir ; Save
        StrCpy $InstDir "$InstDir\bar" 
        !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
        Pop $InstDir ; Restore
    
        !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\data"
        !insertmacro UNINSTALL.LOG_END_UNINSTALL
        DeleteRegKey /ifempty ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}"
    
        ; Because the uninstaller and the .dat were located in their own (unlogged) folders
        ; we need to manually delete them:
        Delete "$INSTDIR\foo\uninst.exe"
        RMDir "$INSTDIR\foo"
        Delete "$INSTDIR\bar\${UNINSTALL_LOG}.dat"
        RMDir "$INSTDIR\bar"
    
        RMDir "$INSTDIR"
    
    SectionEnd