add the inner/outer paradigm for signed uninstaller

This commit is contained in:
Stephen Birarda 2016-01-12 17:09:21 -08:00
parent 3b12eef79b
commit d6f50b66d6

View file

@ -31,6 +31,31 @@
;--------------------------------
;General
!ifdef INNER
!echo "Inner invocation" ; just to see what's going on
OutFile "$%TEMP%\tempinstaller.exe" ; not really important where this is
SetCompress off ; for speed
!else
!echo "Outer invocation"
; Call makensis again, defining INNER. This writes an installer for us which, when
; it is invoked, will just write the uninstaller to some location, and then exit.
; Be sure to substitute the name of this script here.
!system "$\"${NSISDIR}\makensis$\" /DINNER <name_of_script>.nsi" = 0
; So now run that installer we just created as %TEMP%\tempinstaller.exe. Since it
; calls quit the return value isn't zero.
!system "$%TEMP%\tempinstaller.exe" = 2
; That will have written an uninstaller binary for us. Now we sign it with your
; favourite code signing tool.
!system "signcode <signing options> $%TEMP%\uninstaller.exe" = 0
; Good. Now we can carry on writing the real installer.
;Name and file
Name "@CPACK_NSIS_PACKAGE_NAME@"
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
@ -40,6 +65,7 @@
;Require administrator access
RequestExecutionLevel admin
!endif
@CPACK_NSIS_DEFINES@
@ -648,8 +674,15 @@ Section "-Core installation"
;Store installation folder
WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
;Package the signed uninstaller produced by the inner loop
!ifndef INNER
SetOutPath $INSTDIR
; this packages the signed uninstaller
File $%TEMP%\uninstaller.exe
!endif
Push "DisplayName"
Push "@CPACK_NSIS_DISPLAY_NAME@"
Call ConditionalAddToRegisty
@ -951,6 +984,10 @@ FunctionEnd
;--------------------------------
;Uninstaller Section
; the normal uninstaller section is only defined for inner (they're not needed in the "outer"
; installer and will just cause warnings because there is no WriteInstaller command)
!ifdef INNER
Section "Uninstall"
ReadRegStr $START_MENU SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
@ -1046,6 +1083,7 @@ Section "Uninstall"
Call un.RemoveFromPath
doNotRemoveFromPath:
SectionEnd
!endif
;--------------------------------
; determine admin versus local install
@ -1058,6 +1096,18 @@ SectionEnd
; "Program Files" for AllUsers, "My Documents" for JustMe...
Function .onInit
!ifdef INNER
; If INNER is defined, then we aren't supposed to do anything except write out
; the installer. This is better than processing a command line option as it means
; this entire code path is not present in the final (real) installer.
WriteUninstaller "$%TEMP%\uninstaller.exe"
; just bail out quickly when running the "inner" installer
Quit
!endif
StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString"