diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 77155d3e9..210cc88e9 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -525,17 +525,19 @@ See also `initialize_by_default`. ### `initialize_by_default` -Default value for the option added by `initialize_conda`. The default -is true for GUI installers (EXE, PKG) and false for shell installers. The user -is able to change the default during interactive installation. NOTE: For Windows, -`AddToPath` is disabled when `InstallationType=AllUsers`. +Default value for the option added by `initialize_conda`. The default is +true for PKG installers, and false for EXE and SH shell installers. +The user is able to change the default during interactive installations. +Non-interactive installations are not affected by this value: users must explicitly request +to add to `PATH` via CLI options. +NOTE: For Windows, `/AddToPath` is disabled when `/InstallationType=AllUsers`. Only applies if `initialize_conda` is not false. ### `register_python` -Whether to offer the user an option to register the installed Python instance as the -system's default Python. (Windows only) +If the installer installs a Python instance, offer the user an option to register the installed Python instance as the +system's default Python. Defaults to `true` for GUI and `false` for CLI installations. (Windows only) ### `register_python_default` diff --git a/constructor/_schema.py b/constructor/_schema.py index 2e1785b13..d50cac46a 100644 --- a/constructor/_schema.py +++ b/constructor/_schema.py @@ -692,17 +692,19 @@ class ConstructorConfiguration(BaseModel): """ initialize_by_default: bool | None = None """ - Default value for the option added by `initialize_conda`. The default - is true for GUI installers (EXE, PKG) and false for shell installers. The user - is able to change the default during interactive installation. NOTE: For Windows, - `AddToPath` is disabled when `InstallationType=AllUsers`. + Default value for the option added by `initialize_conda`. The default is + true for PKG installers, and false for EXE and SH shell installers. + The user is able to change the default during interactive installations. + Non-interactive installations are not affected by this value: users must explicitly request + to add to `PATH` via CLI options. + NOTE: For Windows, `/AddToPath` is disabled when `/InstallationType=AllUsers`. Only applies if `initialize_conda` is not false. """ register_python: bool = True """ - Whether to offer the user an option to register the installed Python instance as the - system's default Python. (Windows only) + If the installer installs a Python instance, offer the user an option to register the installed Python instance as the + system's default Python. Defaults to `true` for GUI and `false` for CLI installations. (Windows only) """ register_python_default: bool | None = False """ diff --git a/constructor/data/construct.schema.json b/constructor/data/construct.schema.json index 78f371941..228b82946 100644 --- a/constructor/data/construct.schema.json +++ b/constructor/data/construct.schema.json @@ -750,7 +750,7 @@ } ], "default": null, - "description": "Default value for the option added by `initialize_conda`. The default is true for GUI installers (EXE, PKG) and false for shell installers. The user is able to change the default during interactive installation. NOTE: For Windows, `AddToPath` is disabled when `InstallationType=AllUsers`.\nOnly applies if `initialize_conda` is not false.", + "description": "Default value for the option added by `initialize_conda`. The default is true for PKG installers, and false for EXE and SH shell installers. The user is able to change the default during interactive installations. Non-interactive installations are not affected by this value: users must explicitly request to add to `PATH` via CLI options. NOTE: For Windows, `/AddToPath` is disabled when `/InstallationType=AllUsers`.\nOnly applies if `initialize_conda` is not false.", "title": "Initialize By Default" }, "initialize_conda": { @@ -1076,7 +1076,7 @@ }, "register_python": { "default": true, - "description": "Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only)", + "description": "If the installer installs a Python instance, offer the user an option to register the installed Python instance as the system's default Python. Defaults to `true` for GUI and `false` for CLI installations. (Windows only)", "title": "Register Python", "type": "boolean" }, diff --git a/constructor/nsis/OptionsDialog.nsh b/constructor/nsis/OptionsDialog.nsh index 0b5f15c6d..11c94e5a3 100644 --- a/constructor/nsis/OptionsDialog.nsh +++ b/constructor/nsis/OptionsDialog.nsh @@ -7,30 +7,90 @@ Var mui_AnaCustomOptions Var mui_AnaCustomOptions.AddToPath -Var mui_AnaCustomOptions.RegisterSystemPython Var mui_AnaCustomOptions.PostInstall Var mui_AnaCustomOptions.PreInstall Var mui_AnaCustomOptions.ClearPkgCache Var mui_AnaCustomOptions.CreateShortcuts # These are the checkbox states, to be used by the installer -Var Ana_AddToPath_State -Var Ana_RegisterSystemPython_State Var Ana_PostInstall_State Var Ana_PreInstall_State Var Ana_ClearPkgCache_State Var Ana_CreateShortcuts_State Var Ana_AddToPath_Label -Var Ana_RegisterSystemPython_Label Var Ana_ClearPkgCache_Label Var Ana_PostInstall_Label Var Ana_PreInstall_Label + +!if ${REGISTER_PYTHON_OPTION} == 1 + Var mui_AnaCustomOptions.RegisterSystemPython + Var Ana_RegisterSystemPython_Label + + Function RegisterSystemPython_OnClick + Pop $0 + + # Sync UI with variable + ${NSD_GetState} $0 $1 + ${If} $1 == ${BST_CHECKED} + StrCpy $REG_PY 1 + ${Else} + StrCpy $REG_PY 0 + ${EndIf} + + ShowWindow $Ana_RegisterSystemPython_Label ${SW_HIDE} + ${If} $REG_PY == 1 + SetCtlColors $Ana_RegisterSystemPython_Label ff0000 transparent + ${Else} + SetCtlColors $Ana_RegisterSystemPython_Label 000000 transparent + ${EndIf} + ShowWindow $Ana_RegisterSystemPython_Label ${SW_SHOW} + + # If the button was checked, make sure we're not conflicting + # with another system installed Python + ${If} $REG_PY == 1 + # Check if a Python of the version we're installing + # already exists, in which case warn the user before + # proceeding. + ReadRegStr $2 SHCTX "Software\Python\PythonCore\${PY_VER}\InstallPath" "" + ${If} "$2" != "" + ${AndIf} ${FileExists} "$2\Python.exe" + MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION|MB_DEFBUTTON2 \ + "A version of Python ${PY_VER} (${ARCH}) is already at$\n\ + $2$\n\ + We recommend that if you want ${NAME} registered as your $\n\ + system Python, you unregister this Python first. If you really$\n\ + know this is what you want, click OK, otherwise$\n\ + click cancel to continue.$\n$\n\ + NOTE: Anaconda 1.3 and earlier lacked an uninstall, if$\n\ + you are upgrading an old Anaconda, please delete the$\n\ + directory manually." \ + IDOK KeepSettingLabel + # If they don't click OK, uncheck it + StrCpy $REG_PY 0 + ${NSD_Uncheck} $0 + + KeepSettingLabel: + + ${EndIf} + ${EndIf} + FunctionEnd +!endif + Function mui_AnaCustomOptions_InitDefaults - # Initialize defaults - ${If} $Ana_AddToPath_State == "" - StrCpy $Ana_AddToPath_State ${BST_UNCHECKED} + # AddToPath / conda init default + !if ${INIT_CONDA_OPTION} == 1 + # Ensure we initialize from compile-time default value + StrCpy $INIT_CONDA ${INIT_CONDA_DEFAULT_VALUE} + !else + StrCpy $INIT_CONDA 0 + !endif + + # Register Python default while accounting for existing installations + !if ${REGISTER_PYTHON_OPTION} == 1 + # Ensure we initialize from compile-time default value + StrCpy $REG_PY ${REGISTER_PYTHON_DEFAULT_VALUE} # Default whether to register as system python as: # Enabled - if no system python is registered, OR # a system python which does not exist is registered. @@ -38,11 +98,13 @@ Function mui_AnaCustomOptions_InitDefaults ReadRegStr $2 SHCTX "Software\Python\PythonCore\${PY_VER}\InstallPath" "" ${If} "$2" != "" ${AndIf} ${FileExists} "$2\Python.exe" - StrCpy $Ana_RegisterSystemPython_State ${BST_UNCHECKED} - ${Else} - StrCpy $Ana_RegisterSystemPython_State ${BST_CHECKED} + StrCpy $REG_PY 0 ${EndIf} - ${EndIf} + !else + StrCpy $REG_PY 0 + !endif + + # Shortcuts defaults ${If} $Ana_CreateShortcuts_State == "" ${If} "${ENABLE_SHORTCUTS}" == "yes" StrCpy $Ana_CreateShortcuts_State ${BST_CHECKED} @@ -57,7 +119,7 @@ FunctionEnd Function mui_AnaCustomOptions_Show ; Enforce that the defaults were initialized - ${If} $Ana_AddToPath_State == "" + ${If} $INIT_CONDA == "" Abort ${EndIf} @@ -84,7 +146,7 @@ Function mui_AnaCustomOptions_Show ${NSD_OnClick} $mui_AnaCustomOptions.CreateShortcuts CreateShortcuts_OnClick ${EndIf} - ${If} "${SHOW_ADD_TO_PATH}" != "no" + !if ${INIT_CONDA_OPTION} == 1 # AddToPath is only an option for JustMe installations; it is disabled for AllUsers # installations. (Addresses CVE-2022-26526) ${If} $InstMode = ${JUST_ME} @@ -92,9 +154,18 @@ Function mui_AnaCustomOptions_Show environment variable" IntOp $5 $5 + 11 Pop $mui_AnaCustomOptions.AddToPath - ${NSD_SetState} $mui_AnaCustomOptions.AddToPath $Ana_AddToPath_State + + # Set state of check-box + ${If} $INIT_CONDA == 1 + ${NSD_Check} $mui_AnaCustomOptions.AddToPath + ${Else} + ${NSD_Uncheck} $mui_AnaCustomOptions.AddToPath + ${EndIf} + ${NSD_OnClick} $mui_AnaCustomOptions.AddToPath AddToPath_OnClick - ${If} "${SHOW_ADD_TO_PATH}" == "condabin" + + # Account for the conda mode + ${If} "${INIT_CONDA_MODE}" == "condabin" ${NSD_CreateLabel} 5% "$5u" 90% 20u \ "Adds condabin/, which only contains the 'conda' executables, to PATH. \ Does not require special shortcuts but activation needs \ @@ -107,26 +178,54 @@ Function mui_AnaCustomOptions_Show ${EndIf} IntOp $5 $5 + 20 Pop $Ana_AddToPath_Label + + # Color the label if needed; even if the user has not interacted with the checkbox yet + ${If} $INIT_CONDA = 1 + ${If} "${INIT_CONDA_MODE}" == "classic" + SetCtlColors $Ana_AddToPath_Label ff0000 transparent + ${Else} + # Here INIT_CONDA_MODE equals condabin + SetCtlColors $Ana_AddToPath_Label 000000 transparent + ${EndIf} + ${Else} + SetCtlColors $Ana_AddToPath_Label 000000 transparent + ${EndIf} ${EndIf} - ${EndIf} + !endif - ${If} "${SHOW_REGISTER_PYTHON}" == "yes" + !if ${REGISTER_PYTHON_OPTION} == 1 ${If} $InstMode = ${JUST_ME} StrCpy $1 "my default" ${Else} StrCpy $1 "the system" ${EndIf} + ${NSD_CreateCheckbox} 0 "$5u" 100% 11u "&Register ${NAME} as $1 Python ${PY_VER}" IntOp $5 $5 + 11 Pop $mui_AnaCustomOptions.RegisterSystemPython - ${NSD_SetState} $mui_AnaCustomOptions.RegisterSystemPython $Ana_RegisterSystemPython_State + + # Set state of check-box + ${If} $REG_PY == 1 + ${NSD_Check} $mui_AnaCustomOptions.RegisterSystemPython + ${Else} + ${NSD_Uncheck} $mui_AnaCustomOptions.RegisterSystemPython + ${EndIf} + ${NSD_OnClick} $mui_AnaCustomOptions.RegisterSystemPython RegisterSystemPython_OnClick + ${NSD_CreateLabel} 5% "$5u" 90% 20u \ "Allows other programs, such as VSCode, PyCharm, etc. to automatically \ detect ${NAME} as the primary Python ${PY_VER} on the system." IntOp $5 $5 + 20 Pop $Ana_RegisterSystemPython_Label - ${EndIf} + + # Color the label if needed; even if the user has not interacted with the checkbox yet + ${If} $REG_PY = 1 + SetCtlColors $Ana_RegisterSystemPython_Label ff0000 transparent + ${Else} + SetCtlColors $Ana_RegisterSystemPython_Label 000000 transparent + ${EndIf} + !endif ${NSD_CreateCheckbox} 0 "$5u" 100% 11u "Clear the package cache upon completion" @@ -167,58 +266,24 @@ FunctionEnd Function AddToPath_OnClick Pop $0 - ShowWindow $Ana_AddToPath_Label ${SW_HIDE} - ${NSD_GetState} $0 $Ana_AddToPath_State - ${If} $Ana_AddToPath_State == ${BST_UNCHECKED} - ${Else} - ${If} "${SHOW_ADD_TO_PATH}" == "condabin" - SetCtlColors $Ana_AddToPath_Label 000000 transparent - ${Else} - SetCtlColors $Ana_AddToPath_Label ff0000 transparent - ${EndIf} - ${EndIf} - ShowWindow $Ana_AddToPath_Label ${SW_SHOW} -FunctionEnd - -Function RegisterSystemPython_OnClick - Pop $0 - - ShowWindow $Ana_RegisterSystemPython_Label ${SW_HIDE} - ${NSD_GetState} $0 $Ana_RegisterSystemPython_State - ${If} $Ana_RegisterSystemPython_State == ${BST_UNCHECKED} - SetCtlColors $Ana_RegisterSystemPython_Label ff0000 transparent + # Sync UI with variable + ${NSD_GetState} $0 $1 + ${If} $1 == ${BST_CHECKED} + StrCpy $INIT_CONDA 1 ${Else} - SetCtlColors $Ana_RegisterSystemPython_Label 000000 transparent + StrCpy $INIT_CONDA 0 ${EndIf} - ShowWindow $Ana_RegisterSystemPython_Label ${SW_SHOW} - - # If the button was checked, make sure we're not conflicting - # with another system installed Python - ${If} $Ana_RegisterSystemPython_State == ${BST_CHECKED} - # Check if a Python of the version we're installing - # already exists, in which case warn the user before - # proceeding. - ReadRegStr $2 SHCTX "Software\Python\PythonCore\${PY_VER}\InstallPath" "" - ${If} "$2" != "" - ${AndIf} ${FileExists} "$2\Python.exe" - MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION|MB_DEFBUTTON2 \ - "A version of Python ${PY_VER} (${ARCH}) is already at$\n\ - $2$\n\ - We recommend that if you want ${NAME} registered as your $\n\ - system Python, you unregister this Python first. If you really$\n\ - know this is what you want, click OK, otherwise$\n\ - click cancel to continue.$\n$\n\ - NOTE: Anaconda 1.3 and earlier lacked an uninstall, if$\n\ - you are upgrading an old Anaconda, please delete the$\n\ - directory manually." \ - IDOK KeepSettingLabel - # If they don't click OK, uncheck it - StrCpy $Ana_RegisterSystemPython_State ${BST_UNCHECKED} - ${NSD_SetState} $0 $Ana_RegisterSystemPython_State -KeepSettingLabel: + ShowWindow $Ana_AddToPath_Label ${SW_HIDE} + # Only color it red if it's classic + ${If} $INIT_CONDA == 1 + ${If} "${INIT_CONDA_MODE}" == "classic" + SetCtlColors $Ana_AddToPath_Label ff0000 transparent ${EndIf} + ${Else} + SetCtlColors $Ana_AddToPath_Label 000000 transparent ${EndIf} + ShowWindow $Ana_AddToPath_Label ${SW_SHOW} FunctionEnd Function PostInstall_OnClick diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 371eff0f7..fb93badb6 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -73,30 +73,36 @@ ${Using:StrFunc} StrStr !include "StandaloneUninstallerOptions.nsh" {%- endif %} -!define NAME {{ installer_name }} -!define VERSION {{ installer_version }} -!define COMPANY {{ company }} -!define ARCH {{ arch }} -!define PLATFORM {{ installer_platform }} -!define CONSTRUCTOR_VERSION {{ constructor_version }} +!define NAME {{ installer_name }} +!define VERSION {{ installer_version }} +!define COMPANY {{ company }} +!define ARCH {{ arch }} +!define PLATFORM {{ installer_platform }} +!define CONSTRUCTOR_VERSION {{ constructor_version }} {%- if has_python %} -!define PY_VER {{ pyver_components[:2] | join(".") }} -!define PYVERSION_JUSTDIGITS {{ pyver_components | join("") }} -!define PYVERSION {{ pyver_components | join(".") }} -!define PYVERSION_MAJOR {{ pyver_components[0] }} -{%- endif %} -!define DEFAULT_PREFIX {{ default_prefix }} -!define DEFAULT_PREFIX_DOMAIN_USER {{ default_prefix_domain_user }} -!define DEFAULT_PREFIX_ALL_USERS {{ default_prefix_all_users }} -!define PRE_INSTALL_DESC {{ pre_install_desc }} -!define POST_INSTALL_DESC {{ post_install_desc }} -!define ENABLE_SHORTCUTS {{ enable_shortcuts }} -!define SHOW_REGISTER_PYTHON {{ show_register_python }} -!define SHOW_ADD_TO_PATH {{ show_add_to_path }} -!define PRODUCT_NAME "${NAME} ${VERSION} (${ARCH})" -!define UNINSTALL_NAME "{{ UNINSTALL_NAME }}" -!define UNINSTREG "SOFTWARE\Microsoft\Windows\CurrentVersion\ - \Uninstall\${UNINSTALL_NAME}" +!define PY_VER {{ pyver_components[:2] | join(".") }} +!define PYVERSION_JUSTDIGITS {{ pyver_components | join("") }} +!define PYVERSION {{ pyver_components | join(".") }} +!define PYVERSION_MAJOR {{ pyver_components[0] }} +{% endif %} +!define DEFAULT_PREFIX {{ default_prefix }} +!define DEFAULT_PREFIX_DOMAIN_USER {{ default_prefix_domain_user }} +!define DEFAULT_PREFIX_ALL_USERS {{ default_prefix_all_users }} +!define PRE_INSTALL_DESC {{ pre_install_desc }} +!define POST_INSTALL_DESC {{ post_install_desc }} +!define ENABLE_SHORTCUTS {{ enable_shortcuts }} +!define REGISTER_PYTHON_OPTION {{ '1' if register_python and has_python else '0' }} +!define REGISTER_PYTHON_DEFAULT_VALUE {{ '1' if register_python_default else '0' }} +!define INIT_CONDA_OPTION {{ '1' if initialize_conda else '0' }} +!define INIT_CONDA_MODE "{{ 'condabin' if initialize_conda == 'condabin' else 'classic' }}" +!define INIT_CONDA_DEFAULT_VALUE {{ '1' if initialize_by_default else '0' }} +!define PRODUCT_NAME "${NAME} ${VERSION} (${ARCH})" +!define UNINSTALL_NAME "{{ UNINSTALL_NAME }}" +!define UNINSTREG "SOFTWARE\Microsoft\Windows\CurrentVersion\ + \Uninstall\${UNINSTALL_NAME}" + +var /global INIT_CONDA +var /global REG_PY var /global INSTDIR_JUSTME var /global INSTALLER_VERSION @@ -112,7 +118,9 @@ var /global ARGV_Help var /global ARGV_InstallationType var /global ARGV_AddToPath var /global ARGV_KeepPkgCache +{%- if has_python %} var /global ARGV_RegisterPython +{%- endif %} var /global ARGV_NoRegistry var /global ARGV_NoScripts var /global ARGV_NoShortcuts @@ -303,11 +311,13 @@ FunctionEnd OPTIONS$\n\ -------$\n\ $\n\ - /InstallationType=AllUsers [default: JustMe]$\n\ + /InstallationType=[AllUsers|JustMe] [default: JustMe]$\n\ +{%- if initialize_conda %} /AddToPath=[0|1] [default: 0]$\n\ +{%- endif %} /KeepPkgCache=[0|1] [default: {{ 1 if keep_pkgs else 0 }}]$\n\ -{%- if has_python %} - /RegisterPython=[0|1] [default: AllUsers: 1, JustMe: 0]$\n\ +{%- if has_python and register_python %} + /RegisterPython=[0|1] [default: 0]$\n\ {%- endif %} /NoRegistry=[0|1] [default: AllUsers: 0, JustMe: 0]$\n\ /NoScripts=[0|1] [default: 0]$\n\ @@ -327,14 +337,16 @@ FunctionEnd Install for all users, but don't add to PATH env var:$\n\ > $EXEFILE /InstallationType=AllUsers$\n\ $\n\ -{%- if has_python %} - Install for just me, add to PATH and register as system Python:$\n\ - > $EXEFILE /RegisterPython=1 /AddToPath=1$\n\ +{%- if has_python and register_python %} + Install for just me, and register as system Python:$\n\ + > $EXEFILE /RegisterPython=1$\n\ $\n\ {%- endif %} +{%- if initialize_conda %} Install for just me and add to PATH:$\n\ > $EXEFILE /AddToPath=1$\n\ $\n\ +{%- endif %} Install for just me, with no registry modification (for CI):$\n\ > $EXEFILE /NoRegistry=1$\n\ $\n\ @@ -357,17 +369,46 @@ FunctionEnd ${EndIf} ${EndIf} - ClearErrors -{%- if has_python %} - ${GetOptions} $ARGV "/RegisterPython=" $ARGV_RegisterPython - ${IfNot} ${Errors} - ${If} $ARGV_RegisterPython = "1" - StrCpy $Ana_RegisterSystemPython_State ${BST_CHECKED} - ${ElseIf} $ARGV_RegisterPython = "0" - StrCpy $Ana_RegisterSystemPython_State ${BST_UNCHECKED} + + !if ${REGISTER_PYTHON_OPTION} == 1 + ClearErrors + ${GetOptions} $ARGV "/RegisterPython=" $ARGV_RegisterPython + ${IfNot} ${Errors} + ${If} $ARGV_RegisterPython == "1" + StrCpy $REG_PY 1 + ${ElseIf} $ARGV_RegisterPython == "0" + StrCpy $REG_PY 0 + ${EndIf} + ${Else} + # If we have Errors, the option is not explicitly set by the user + StrCpy $REG_PY 0 ${EndIf} - ${EndIf} -{%- endif %} + + !endif + + !if ${INIT_CONDA_OPTION} == 1 + ClearErrors + ${GetOptions} $ARGV "/AddToPath=" $ARGV_AddToPath + ${IfNot} ${Errors} + ${If} $ARGV_AddToPath = "1" + # To address CVE-2022-26526. + # In AllUsers install mode, do not allow AddToPath as an option. + ${If} $InstMode == ${ALL_USERS} + MessageBox MB_OK|MB_ICONEXCLAMATION \ + "/AddToPath=1 is disabled and ignored in 'All Users' installations" /SD IDOK + ${Print} "/AddToPath=1 is disabled and ignored in 'All Users' installations" + StrCpy $INIT_CONDA 0 + ${Else} + StrCpy $INIT_CONDA 1 + ${EndIf} + ${ElseIf} $ARGV_AddToPath = "0" + StrCpy $INIT_CONDA 0 + ${EndIf} + ${Else} + # If we have Errors, the option is not explicitly set by the user + StrCpy $INIT_CONDA 0 + ${EndIf} + !endif ClearErrors ${GetOptions} $ARGV "/KeepPkgCache=" $ARGV_KeepPkgCache @@ -423,31 +464,6 @@ FunctionEnd !macroend -Function OnInit_Release - ${LogSet} on - !insertmacro ParseCommandLineArgs - - # Parsing the AddToPath option here (and not in ParseCommandLineArgs) to prevent the MessageBox from showing twice. - # For more context, see https://github.com/conda/constructor/pull/584#issuecomment-1347688020 - ClearErrors - ${GetOptions} $ARGV "/AddToPath=" $ARGV_AddToPath - ${IfNot} ${Errors} - ${If} $ARGV_AddToPath = "1" - ${If} $InstMode == ${ALL_USERS} - # To address CVE-2022-26526. - # In AllUsers install mode, do not allow AddToPath as an option. - MessageBox MB_OK|MB_ICONEXCLAMATION "/AddToPath=1 is disabled and ignored in 'All Users' installations" /SD IDOK - ${Print} "/AddToPath=1 is disabled and ignored in 'All Users' installations" - StrCpy $Ana_AddToPath_State ${BST_UNCHECKED} - ${Else} - StrCpy $Ana_AddToPath_State ${BST_CHECKED} - ${EndIf} - ${ElseIf} $ARGV_AddToPath = "0" - StrCpy $Ana_AddToPath_State ${BST_UNCHECKED} - ${EndIf} - ${EndIf} -FunctionEnd - Function InstModePage_RadioButton_OnClick ${LogSet} on Exch $0 @@ -589,6 +605,14 @@ Function .onInit Push $R1 Push $R2 + # 1. Initialize core options default values + Call mui_AnaCustomOptions_InitDefaults + + # 2. Account finally for CLI to potentially override core default values + ${If} ${Silent} + !insertmacro ParseCommandLineArgs + ${EndIf} + InitPluginsDir {%- if TEMP_EXTRA_FILES | length != 0 %} SetOutPath $PLUGINSDIR @@ -596,7 +620,6 @@ Function .onInit File "{{ file }}" {%- endfor %} {%- endif %} - !insertmacro ParseCommandLineArgs # Select the correct registry to look at, depending # on whether it's a 32-bit or 64-bit installer @@ -733,32 +756,11 @@ Function .onInit StrCpy $CheckPathLength "1" ${EndIf} - # Initialize the default settings for the anaconda custom options - Call mui_AnaCustomOptions_InitDefaults - # Override custom options with explicitly given values from construct.yaml. - # If initialize_by_default / register_python_default - # are None, do nothing. Note that these variables exist even when the construct.yaml - # settings are disabled, and the installer will respect them later! -{%- if initialize_conda %} - {%- if initialize_by_default %} - ${If} $InstMode == ${JUST_ME} - StrCpy $Ana_AddToPath_State ${BST_CHECKED} - ${EndIf} - {%- else %} - StrCpy $Ana_AddToPath_State ${BST_UNCHECKED} - {%- endif %} -{%- endif %} - -{%- if register_python %} - StrCpy $Ana_RegisterSystemPython_State {{ '${BST_CHECKED}' if register_python_default else '${BST_UNCHECKED}' }} -{%- endif %} StrCpy $CheckPathLength "{{ 1 if check_path_length else 0 }}" StrCpy $Ana_ClearPkgCache_State {{ '${BST_UNCHECKED}' if keep_pkgs else '${BST_CHECKED}' }} StrCpy $Ana_PreInstall_State {{ '${BST_CHECKED}' if pre_install_exists else '${BST_UNCHECKED}' }} StrCpy $Ana_PostInstall_State {{ '${BST_CHECKED}' if post_install_exists else '${BST_UNCHECKED}' }} - Call OnInit_Release - ${Print} "Welcome to ${NAME} ${VERSION}$\n" Pop $R2 @@ -1591,19 +1593,19 @@ Section "Install" call AbortRetryNSExecWait ${EndIf} -{% if initialize_conda %} - ${If} ${FileExists} "$INSTDIR\.nonadmin" - ${If} $Ana_AddToPath_State = ${BST_CHECKED} - !insertmacro AddRemovePath "add" "" + !if ${INIT_CONDA_OPTION} == 1 + ${If} ${FileExists} "$INSTDIR\.nonadmin" + ${If} $INIT_CONDA = 1 + !insertmacro AddRemovePath "add" "" + ${EndIf} ${EndIf} - ${EndIf} -{%- endif %} + !endif {%- if has_python %} # Create registry entries saying this is the system Python # (for this version) !define PYREG "Software\Python\PythonCore\${PY_VER}" - ${If} $Ana_RegisterSystemPython_State == ${BST_CHECKED} + ${If} $REG_PY == 1 WriteRegStr SHCTX "${PYREG}\Help\Main Python Documentation" \ "Main Python Documentation" \ "$INSTDIR\Doc\python${PYVERSION_JUSTDIGITS}.chm" diff --git a/constructor/winexe.py b/constructor/winexe.py index 1af81dfc3..d225182af 100644 --- a/constructor/winexe.py +++ b/constructor/winexe.py @@ -166,8 +166,6 @@ def make_nsi( "pre_install_desc": info["pre_install_desc"], "post_install_desc": info["post_install_desc"], "enable_shortcuts": "yes" if info["_enable_shortcuts"] is True else "no", - "show_register_python": "yes" if info.get("register_python", True) else "no", - "show_add_to_path": info.get("initialize_conda", "classic") or "no", "outfile": info["_outpath"], "vipv": make_VIProductVersion(info["version"]), "constructor_version": info["CONSTRUCTOR_VERSION"], diff --git a/docs/source/cli-options.md b/docs/source/cli-options.md index 97bd1ea8b..cad946d87 100644 --- a/docs/source/cli-options.md +++ b/docs/source/cli-options.md @@ -72,7 +72,7 @@ Windows installers have the following CLI options available: - `/NoShortcuts=[0|1]`: If set to `1`, the installer will not create any shortcuts. Defaults to `0`. - `/RegisterPython=[0|1]`: Whether to register Python as default in the Windows registry. Defaults - to `1`. This is preferred to `AddToPath`. + to `0`. This is preferred to `AddToPath`. - `/D` (directory): sets the default installation directory. Note that even if the path contains spaces, it must be the last parameter used in the command line and must not contain any quotes. Only absolute paths are supported. diff --git a/docs/source/construct-yaml.md b/docs/source/construct-yaml.md index 77155d3e9..210cc88e9 100644 --- a/docs/source/construct-yaml.md +++ b/docs/source/construct-yaml.md @@ -525,17 +525,19 @@ See also `initialize_by_default`. ### `initialize_by_default` -Default value for the option added by `initialize_conda`. The default -is true for GUI installers (EXE, PKG) and false for shell installers. The user -is able to change the default during interactive installation. NOTE: For Windows, -`AddToPath` is disabled when `InstallationType=AllUsers`. +Default value for the option added by `initialize_conda`. The default is +true for PKG installers, and false for EXE and SH shell installers. +The user is able to change the default during interactive installations. +Non-interactive installations are not affected by this value: users must explicitly request +to add to `PATH` via CLI options. +NOTE: For Windows, `/AddToPath` is disabled when `/InstallationType=AllUsers`. Only applies if `initialize_conda` is not false. ### `register_python` -Whether to offer the user an option to register the installed Python instance as the -system's default Python. (Windows only) +If the installer installs a Python instance, offer the user an option to register the installed Python instance as the +system's default Python. Defaults to `true` for GUI and `false` for CLI installations. (Windows only) ### `register_python_default` diff --git a/examples/custom_nsis_template/custom.nsi.tmpl b/examples/custom_nsis_template/custom.nsi.tmpl index ff6526fc9..1ed5b41f3 100644 --- a/examples/custom_nsis_template/custom.nsi.tmpl +++ b/examples/custom_nsis_template/custom.nsi.tmpl @@ -55,8 +55,6 @@ Unicode "true" # OptionsDialog.nsh plug-in constructor uses !define PRE_INSTALL_DESC __PRE_INSTALL_DESC__ !define POST_INSTALL_DESC __POST_INSTALL_DESC__ -!define SHOW_REGISTER_PYTHON __SHOW_REGISTER_PYTHON__ -!define SHOW_ADD_TO_PATH __SHOW_ADD_TO_PATH__ !define PRODUCT_NAME "${NAME} Uninstaller Patch" !define UNINSTREG "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index aedaf28ff..ef09adfcd 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -9,7 +9,7 @@ channels: specs: - python=3.9 - conda # conda is required for extra_envs - - miniforge_console_shortcut # [win] + - miniforge_console_shortcut 1.* # [win] exclude: # [unix] - tk # [unix] extra_envs: diff --git a/news/1105-improve-handling-of-certain-options b/news/1105-improve-handling-of-certain-options new file mode 100644 index 000000000..171008d30 --- /dev/null +++ b/news/1105-improve-handling-of-certain-options @@ -0,0 +1,22 @@ +### Enhancements + +* EXE: Improve handling of options `initialize_conda`, `register_python` with their corresponding default values. The behavior of these options + with respect to `initialize_by_default` and `register_python_default` is now consistent with `.sh` and `.pkg` installers. + Windows CLI installations now don't add `conda` to `PATH` or register Python by default, and command-line arguments are + only parsed when installing in silent mode (enabled with the flag `/S`). (#1003, #1004 via #1105) + +### Bug fixes + +* + +### Deprecations + +* + +### Docs + +* + +### Other + +*