Search code examples
installationnsisuninstallation

Waiting for NSIS uninstaller to finish in NSIS installer either fails or the uninstaller won't be deleted


Using NSIS, I want to call the uninstaller of a previously installed version from my installer before installing the new version. The proposed solution for this is to execute the following command:

ExecWait '"$INSTDIR\uninstall.exe" _?=$INSTDIR'

As far as I understood, the _?=$INSTDIR is needed to make the ExecWait truly waiting. Without it, NSIS would copy the uninstaller to the temp directory, start it there, and then return before the uninstaller finishes. The problem with this solution is, that the uninstaller is directly executed in the $INSTDIR. This leads to the effect that the following command in my uninstaller fails:

Delete "$INSTDIR\uninstall.exe"

As far as I understood, the reason why uninstall.exe is not deleted is, that a file which is currently being executed cannot be deleted. To summarize my problem:

ExecWait '"$INSTDIR\uninstall.exe"'

doesn't wait for the uninstaller to finish and

ExecWait '"$INSTDIR\uninstall.exe" _?=$INSTDIR'

doesn't allow the uninstaller to delete itself. Does anybody know, how to wait for an uninstaller to finish while at the same time allowing the uninstaller to instantly delete itself within the uninstallation process?


Solution

  • The _?= parameter tells the uninstaller that it should not copy itself to %temp% and execute that copy without waiting for it to complete. The path after _?= is used to initialize $InstDir in the uninstaller.

    In your installer you can do something like this:

    InitPluginsDir
    ;ReadRegStr $oldinstall ... ; Somehow detect old install
    CreateDirectory "$pluginsdir\unold" ; Make sure plugins do not conflict with a old uninstaller 
    CopyFiles /SILENT /FILESONLY "$oldinstall\uninst.exe" "$pluginsdir\unold"
    ExecWait '"$pluginsdir\unold\uninst.exe" _?=$oldinstall'