Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The .conda directory is not being created on Windows #461

Closed
jlstevens opened this issue Sep 20, 2021 · 1 comment · Fixed by #546
Closed

The .conda directory is not being created on Windows #461

jlstevens opened this issue Sep 20, 2021 · 1 comment · Fixed by #546
Assignees
Labels
locked [bot] locked due to inactivity os::windows relevant to Windows source::community catch-all for issues filed by community members type::bug describes erroneous operation, use severity::* to classify the type

Comments

@jlstevens
Copy link
Contributor

jlstevens commented Sep 20, 2021

When trying to build a Windows installer (win-64, tested on Windows 10), it was found that the uninstaller wasn't removing menu entries but only in some Windows environments and not others. After some investigation, it turned out that the environments where the uninstaller does work properly are the ones where a .conda directory already existed due to a previous Miniconda/Anaconda installation.

The problem seems to be that the .conda directory (usually in $HOME) is not created by the installers built by constructor. In turn, it seems that the issue with the uninstaller (i.e. not removing menu items) goes away when the available environments can be found in the environments.txt file of the .conda directory (when present).

In conclusion, constructor built installers do not appear to be creating the .conda directory when they should while the vanilla Miniconda/Anaconda installers have no such issue. I've discussed this with @chenghlee and the root cause of this discrepancy is currently being investigated.

@jlstevens jlstevens added the type::bug describes erroneous operation, use severity::* to classify the type label Sep 20, 2021
@chenghlee chenghlee self-assigned this Sep 20, 2021
@chenghlee chenghlee added source::community catch-all for issues filed by community members os::windows relevant to Windows labels Sep 20, 2021
@jaimergp
Copy link
Contributor

Some notes from my investigation:

The uninstaller is built with these instructions:

Section "Uninstall"
# Remove menu items, path entries
DetailPrint "Deleting @NAME@ menus..."
nsExec::ExecToLog '"$INSTDIR\_conda.exe" constructor --prefix "$INSTDIR" --rm-menus'
# ensure that MSVC runtime DLLs are on PATH during uninstallation
ReadEnvStr $0 PATH
# set PATH for the installer process, so that MSVC runtimes get found OK
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("PATH", \
"$INSTDIR;$INSTDIR\Library\mingw-w64\bin;$INSTDIR\Library\usr\bin;$INSTDIR\Library\bin;$INSTDIR\Scripts;$INSTDIR\bin;$0;$0\system32;$0\system32\Wbem").r0'
# our newest Python builds have a patch that allows us to control the PATH search stuff much more
# carefully. More info at https://docs.conda.io/projects/conda/en/latest/user-guide/troubleshooting.html#solution
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_DLL_SEARCH_MODIFICATION_ENABLE", "1").r0'
!insertmacro ExecWaitLibNsisCmd "pre_uninstall"
!insertmacro ExecWaitLibNsisCmd "rmpath"
!insertmacro ExecWaitLibNsisCmd "rmreg"
DetailPrint "Removing files and folders..."
nsExec::Exec 'cmd.exe /k RMDIR /Q/S "$INSTDIR"'
# In case the last command fails, run the slow method to remove leftover
RMDir /r /REBOOTOK "$INSTDIR"
DeleteRegKey SHCTX "${UNINSTREG}"
# If Anaconda was registered as the official Python for this version,
# remove it from the registry
ReadRegStr $0 SHCTX "Software\Python\PythonCore\${PY_VER}\InstallPath" ""
${If} $0 == "$INSTDIR"
DeleteRegKey SHCTX "Software\Python\PythonCore\${PY_VER}"
${EndIf}
SectionEnd

The menu removal happens through the bundled conda-standalone executable, which itself bundles the _nsis.py script in constructor - this is the function that gets called with the --rm-menus option:

def rm_menus(prefix=None, root_prefix=None):
try:
import menuinst
from conda.base.context import context
menuinst
except (ImportError, OSError):
return
try:
envs = get_conda_envs()
envs = list(envs) # make sure `envs` is iterable
except Exception as e:
out("Failed to get conda environments list\n")
err("Error: %s\n" % str(e))
err("Traceback:\n%s\n" % traceback.format_exc(20))
return
envs_dirs = list(context.envs_dirs)
if prefix is not None:
envs_dirs.append(prefix)
for env in envs:
env = str(env) # force `str` so that `os.path.join` doesn't fail
for envs_dir in envs_dirs:
# Make sure the environment is from one of the directory in
# `envs_dirs` to avoid picking up environment from other
# distributions. Not perfect but better than no checking
if envs_dir in env:
mk_menus(remove=True, prefix=env, root_prefix=root_prefix)

We can clearly see that a non-existing .conda/environments.txt will make this "just-in-case" error checking.

Why do we need this environments check? I guess because constructor was designed as a conda installer, so the user might have created more environments using it. However, some people use constructors to distribute installers without conda, so this makes not sense in that use case. We should have a fallback mode there that doesn't assume .conda exists. In those cases, the installer probably didn't have conda bundled (or was never executed), which means we can just clear the passed prefix normally.

PR coming soon.

@larsoner larsoner moved this to Done in 🧭 Planning Aug 15, 2022
@github-actions github-actions bot added the locked [bot] locked due to inactivity label Aug 16, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
locked [bot] locked due to inactivity os::windows relevant to Windows source::community catch-all for issues filed by community members type::bug describes erroneous operation, use severity::* to classify the type
Projects
Archived in project
3 participants