* admin/nt/dist-build/emacs.nsi: (Uninstall) delete only one Emacs
authorCorwin Brust <corwin@bru.st>
Mon, 23 Dec 2024 05:08:08 +0000 (23:08 -0600)
committerCorwin Brust <corwin@bru.st>
Mon, 23 Dec 2024 05:08:08 +0000 (23:08 -0600)
Previously, the uninstaller would recursively, unconditionally, remove
the parent folder in which Emacs was installed (the folder selected by
when running the installer), into which the installer places a folder
named for the given release (e.g. emacs-30.1).  This was a problem
during uinstalation when the selected folder contained other versions of
Emacs the user did not wish to remove.  Additionally, deleting Start Menu
short-cuts did not work (bug#68756).

Some installer language now better reflects that users are not
required to "Accept" the GNU Public License in order to use (etc.)
Emacs (bug#67667).

Users selections related to where to create (or not create) Start Menu
shortcuts are no longer ignored. (bug#75013)

Emacs (as installed by the installer) can now be uninstalled via
Windows' Add/Remove Progrms Control Panel.

The uninstaller will now remove (empty) parent folders, both under
Program Files and (when creation of shortcuts is enabled) under the
select Start Menu location.

admin/nt/dist-build/emacs.nsi

index 557bb106dde8150bb8e97f17efbf40ebc19b67b5..b8226d69423c8ae600ee29714c3b659505996813 100644 (file)
@@ -8,7 +8,10 @@ Outfile "emacs-${OUT_VERSION}-installer.exe"
 SetCompressor /solid lzma
 
 Var StartMenuFolder
+Var UninstallerPath
 
+!define UNINST_KEY \
+    "Software\Microsoft\Windows\CurrentVersion\Uninstall\emacs-${VERSION_BRANCH}"
 
 !define MUI_WELCOMEPAGE_TITLE "Emacs"
 !define MUI_WELCOMEPAGE_TITLE_3LINES
@@ -20,16 +23,27 @@ Var StartMenuFolder
 
 !insertmacro MUI_PAGE_WELCOME
 
-
-!define MUI_LICENSEPAGE_TEXT_TOP "The GNU General Public License"
+# licensing/about click-though page
+!define MUI_PAGE_HEADER_TEXT "Emacs is Free Software"
+!define MUI_PAGE_HEADER_SUBTEXT "A component of the GNU operating system."
+!define MUI_LICENSEPAGE_TEXT_TOP "This program is free software."
+!define MUI_LICENSEPAGE_TEXT_BOTTOM "You can redistribute this program and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License (as above), or (at your option) any later version."
+!define MUI_LICENSEPAGE_BUTTON "OK"
 !insertmacro MUI_PAGE_LICENSE "emacs-${VERSION_BRANCH}\share\emacs\${EMACS_VERSION}\lisp\COPYING"
 
+# user option page: installation path
 !insertmacro MUI_PAGE_DIRECTORY
-!insertmacro MUI_PAGE_INSTFILES
 
+# user option page: start menu shortcut
 !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
 
+# user option confirm/begin install
+!insertmacro MUI_PAGE_INSTFILES
+
+# uninstaller confirmation/options (no options)
 !insertmacro MUI_UNPAGE_CONFIRM
+
+# uninstaller begin
 !insertmacro MUI_UNPAGE_INSTFILES
 
 !insertmacro MUI_LANGUAGE "English"
@@ -39,23 +53,35 @@ function .onInit
     StrCpy $INSTDIR "$PROGRAMFILES64\Emacs"
 functionend
 
-
+# main section logic, run after confirming installation
 Section
 
-  SetOutPath $INSTDIR
+  # insisting on installing shortcuts for "all users"
+  # might ensure uninstall can remove shortcuts we created
+  # SetShellVarContext all
 
+  # extract program files
+  SetOutPath $INSTDIR
   File /r emacs-${VERSION_BRANCH}
 
   # define uninstaller name
-  WriteUninstaller $INSTDIR\Uninstall.exe
+  StrCpy $UninstallerPath "$INSTDIR\Uninstall-${VERSION_BRANCH}.exe"
+
+  # create uninstaller
+  WriteUninstaller "$UninstallerPath"
+
+  # add registry key to enable uninstall from control panel
+  WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "GNU Emacs ${VERSION_BRANCH}"
+  WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$UninstallerPath$\""
 
-  !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
   ;Create shortcuts
+  !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
   CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
-  CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
-
+  CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" \
+      "$UninstallerPath"
+  CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Emacs.lnk" \
+      "$INSTDIR\emacs-${VERSION_BRANCH}\bin\runemacs.exe"
   !insertmacro MUI_STARTMENU_WRITE_END
-  CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Emacs.lnk" "$INSTDIR\emacs-${VERSION_BRANCH}\bin\runemacs.exe"
 SectionEnd
 
 
@@ -63,15 +89,50 @@ SectionEnd
 # the section will always be named "Uninstall"
 Section "Uninstall"
 
-  # Always delete uninstaller first
-  Delete "$INSTDIR\Uninstall.exe"
+  # remove All Users shortcuts only
+  # SetShellVarContext all
+
+  # retreive/recalculate uninstaller location
+  StrCpy $UninstallerPath "$INSTDIR\Uninstall-${VERSION_BRANCH}.exe"
+
+  # remove registry key
+  DeleteRegKey HKLM "${UNINST_KEY}"
 
-  # now delete installed directory
-  RMDir /r "$INSTDIR"
-  RMDir "$INSTDIR"
+  # delete uninstaller
+  Delete "$INSTDIR\Uninstall-${VERSION_BRANCH}.exe"
 
+  # retreive/reclculate startmenu shortcuts location
   !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
+  StrCpy $StartMenuFolder "$SMPROGRAMS\$StartMenuFolder"
+
+  # remove Start Menu Program shortcuts
+  Delete "$StartMenuFolder\Emacs.lnk"
+  Delete "$StartMenuFolder\Uninstall.lnk"
+
+  # remove empty startmenu parents up to $SMPROGRAMS
+  startMenuDeleteLoop:
+    ClearErrors
+    RMDir $StartMenuFolder
+    GetFullPathName $StartMenuFolder "$StartMenuFolder\.."
+    IfErrors startMenuDeleteLoopDone
+    StrCmp $StartMenuFolder $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
+
+  # we're basically using GOTO, above, so we should get here..
+  startMenuDeleteLoopDone:
+
+  # next we remove stuff from program-files/instalation path
+  # start with recursive delete of the Emacs we installed
+  RMDir /r "$INSTDIR\emacs-${VERSION_BRANCH}"
+
+  # now walk parents of installation directory, deleting if empty
+  instDirDeleteLoop:
+    ClearErrors
+    RMDir $INSTDIR
+    GetFullPathName $INSTDIR "$INSTDIR\.."
+    IfErrors instDirDeleteLoopDone
+    StrCmp $INSTDIR $PROGRAMFILES64 instDirDeleteLoopDone instDirDeleteLoop
+
+  # final clean-up (after removing from startmenu and progfiles)
+  instDirDeleteLoopDone:
 
-  Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk"
-  RMDir "$SMPROGRAMS\$StartMenuFolder"
 SectionEnd