From 1a6d9d39b032fa984c4ac123ee287c9c4c94b156 Mon Sep 17 00:00:00 2001 From: arnonm <3808041+arnonm@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:29:55 +0200 Subject: [PATCH] Win installer: add option to install in current user (default) or all users Issue: #5276 Signed-off-by: arnonm <3808041+arnonm@users.noreply.github.com> [squashed commits; rebased to master] Signed-off-by: Andreas Buchen --- portfolio-product/installer/installer.nsi | 145 +++++++++++++++++++--- 1 file changed, 127 insertions(+), 18 deletions(-) diff --git a/portfolio-product/installer/installer.nsi b/portfolio-product/installer/installer.nsi index f7cad039c4..4d5ab51e8e 100644 --- a/portfolio-product/installer/installer.nsi +++ b/portfolio-product/installer/installer.nsi @@ -7,11 +7,20 @@ !define APPINI "PortfolioPerformance.ini" !define FOLDER_NAME "PortfolioPerformance" !define INPUT_DIR "..\target\products\name.abuchen.portfolio.distro.product\win32\win32\x86_64\portfolio" -!define INSTDIR "$LOCALAPPDATA\Programs\${FOLDER_NAME}" !define INSTALLSIZE 177818 # size (in kB) !define PUBLISHER "Andreas Buchen" !include nsDialogs.nsh +!include LogicLib.nsh +!include FileFunc.nsh + +RequestExecutionLevel user + +Var InstallType +Var InstallTypeFromCmdLine +Var Dialog +Var RadioUser +Var RadioAllUsers OutFile "..\target\products\${EXECUTABLENAME}-${SOFTWARE_VERSION}-setup.exe" Name "${APPNAME}" @@ -25,11 +34,88 @@ ShowInstDetails nevershow InstProgressFlags smooth ManifestDPIAware true -InstallDir "${INSTDIR}" - +Page custom InstallTypePage InstallTypePageLeave Page directory Page instfiles + +Function .onInit + Var /GLOBAL cmdLineParams + Var /GLOBAL allUsersFlag + Var /GLOBAL currentUserFlag + + StrCpy $InstallType "user" + StrCpy $InstallTypeFromCmdLine "0" + StrCpy $INSTDIR "$LOCALAPPDATA\Programs\${FOLDER_NAME}" + + # Check for command line parameters + ${GetParameters} $cmdLineParams + + # Check for /AllUsers flag + ClearErrors + ${GetOptions} $cmdLineParams "/AllUsers" $allUsersFlag + ${IfNot} ${Errors} + StrCpy $InstallType "allusers" + StrCpy $INSTDIR "$PROGRAMFILES\${FOLDER_NAME}" + StrCpy $InstallTypeFromCmdLine "1" + ${EndIf} + + # Check for /CurrentUser flag + ClearErrors + ${GetOptions} $cmdLineParams "/CurrentUser" $currentUserFlag + ${IfNot} ${Errors} + StrCpy $InstallType "user" + StrCpy $INSTDIR "$LOCALAPPDATA\Programs\${FOLDER_NAME}" + StrCpy $InstallTypeFromCmdLine "1" + ${EndIf} +FunctionEnd + +Function InstallTypePage + # Skip this page if installation type was specified via command line + ${If} $InstallTypeFromCmdLine == "1" + Abort + ${EndIf} + + nsDialogs::Create 1018 + Pop $Dialog + + ${If} $Dialog == error + Abort + ${EndIf} + + ${NSD_CreateLabel} 0 0 100% 24u "Choose installation type:" + Pop $0 + + ${NSD_CreateRadioButton} 10 30u 100% 12u "Install for current user only (recommended)" + Pop $RadioUser + ${NSD_OnClick} $RadioUser OnRadioUser + + ${NSD_CreateRadioButton} 10 50u 100% 12u "Install for all users (requires administrator privileges)" + Pop $RadioAllUsers + ${NSD_OnClick} $RadioAllUsers OnRadioAllUsers + + ${If} $InstallType == "user" + ${NSD_Check} $RadioUser + ${Else} + ${NSD_Check} $RadioAllUsers + ${EndIf} + + nsDialogs::Show +FunctionEnd + +Function OnRadioUser + StrCpy $InstallType "user" + StrCpy $INSTDIR "$LOCALAPPDATA\Programs\${FOLDER_NAME}" +FunctionEnd + +Function OnRadioAllUsers + StrCpy $InstallType "allusers" + StrCpy $INSTDIR "$PROGRAMFILES\${FOLDER_NAME}" +FunctionEnd + +Function InstallTypePageLeave +FunctionEnd + Section Var /GLOBAL APPNAMEFULL @@ -45,17 +131,17 @@ Section # all files #SetOverWrite try - File /r "${INPUT_DIR}\*" + File /r /x "p2" "${INPUT_DIR}\*" # uninstall.exe WriteUninstaller "$INSTDIR\uninstall.exe" - - AccessControl::GrantOnFile "$INSTDIR" "(BU)" "GenericRead + GenericWrite + Delete" - Pop $0 - ${If} $0 == error - Pop $0 - DetailPrint `AccessControl error: $0` - ${EndIf} + # AccessControl plugin not available in standard NSIS installation + # AccessControl::GrantOnFile "$INSTDIR" "(BU)" "GenericRead + GenericWrite + Delete" + # Pop $0 + # ${If} $0 == error + # Pop $0 + # DetailPrint `AccessControl error: $0` + # ${EndIf} # shortcuts CreateDirectory "$SMPROGRAMS\$APPNAMEFULL" @@ -64,8 +150,21 @@ Section WriteINIStr "$SMPROGRAMS\$APPNAMEFULL\$APPNAMEFULL Forum.URL" "InternetShortcut" "URL" "https://forum.portfolio-performance.info" CreateShortCut "$SMPROGRAMS\$APPNAMEFULL\Uninstall $APPNAMEFULL.lnk" "$INSTDIR\uninstall.exe" - # register uninstaller - # see http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller + # register uninstaller based on installation type + ${If} $InstallType == "allusers" + SetShellVarContext all + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayName" "$APPNAMEFULL" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "InstallLocation" "$\"$INSTDIR$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayIcon" "$\"$INSTDIR\${APPEXE}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayVersion" "${SOFTWARE_VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "Publisher" "${PUBLISHER}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "NoRepair" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "EstimatedSize" ${INSTALLSIZE} + ${Else} + SetShellVarContext current WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayName" "$APPNAMEFULL" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" @@ -73,16 +172,22 @@ Section WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayIcon" "$\"$INSTDIR\${APPEXE}$\"" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "DisplayVersion" "${SOFTWARE_VERSION}" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "Publisher" "${PUBLISHER}" - # there is no option for modifying or repairing the install WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "NoModify" 1 WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "NoRepair" 1 - # set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size - WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "EstimatedSize" ${INSTALLSIZE} + WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\$APPNAMEFULL" "EstimatedSize" ${INSTALLSIZE} + ${EndIf} SectionEnd Section "Uninstall" + # Detect installation type from registry + ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" + ${If} $0 != "" + SetShellVarContext all + ${Else} + SetShellVarContext current + ${EndIf} # all files but not workspace RMDir /r $INSTDIR\configuration RMDir /r $INSTDIR\features @@ -93,8 +198,12 @@ Section "Uninstall" Delete $INSTDIR\${APPINI} # remove uninstaller from the registry - DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - +ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" + ${If} $0 != "" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" + ${Else} + DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" + ${EndIf} # remove shortcuts RMDir /r "$SMPROGRAMS\${APPNAME}" # Delete "$SMPROGRAMS\${APPNAME}"