menuinst
menuinst copied to clipboard
File types not associated when using file_extensions on Windows
Checklist
- [X] I added a descriptive title
- [X] I searched open reports and couldn't find a duplicate
What happened?
@jaimergp, I get several errors when using file_extensions
. The constructor
-based installer successfully installs the environment and shortcuts, however file types don't seem to be associated with Spyder, i.e. Spyder is not an available application to "open with" for expected file types.
Additionally, attempting to uninstall or install with menuinst
results in the following errors.
Attempt to uninstall shortcut
[spyder](base) C:\Users\rclary>set bp=%LOCALAPPDATA%\spyder-6
[spyder](base) C:\Users\rclary>set tp=%bp%\envs\spyder-runtime
[spyder](base) C:\Users\rclary>set menu=%tp%\Menu\spyder-menu.json
[spyder](base) C:\Users\rclary>python -c "from menuinst.api import remove; remove(r'%menu%', target_prefix=r'%tp%', base_prefix=r'%bp%')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\utils.py", line 426, in wrapper_elevate
return func(
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\api.py", line 84, in remove
paths += menu_item.remove()
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win.py", line 173, in remove
self._unregister_file_extensions()
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win.py", line 375, in _unregister_file_extensions
unregister_file_extension(ext, identifier, mode=self.menu.mode)
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 88, in unregister_file_extension
_reg_exe("delete", fr"{root_str}\Software\Classes\{identifier}")
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 25, in _reg_exe
return logged_run(["reg.exe", *args, "/f"], check=True)
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\utils.py", line 470, in logged_run
process.check_returncode()
File "C:\Users\rclary\AppData\Local\spyder-6\lib\subprocess.py", line 457, in check_returncode
raise CalledProcessError(self.returncode, self.args, self.stdout,
subprocess.CalledProcessError: Command '['reg.exe', 'delete', 'HKCU\\Software\\Classes\\spyder-6.AssocFilec', '/f']' returned non-zero exit status 1.
[spyder](base) C:\Users\rclary>reg.exe delete HKLM\Software\Classes\spyder-6.AssocFilec /f
ERROR: The system was unable to find the specified registry key or value.
Attempt to install shortcut
[spyder](base) C:\Users\rclary>python -c "from menuinst.api import install; Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\utils.py", line 426, in wrapper_elevate
return func(
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\api.py", line 62, in install
paths += menu_item.create()
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win.py", line 167, in create
self._register_file_extensions()
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win.py", line 365, in _register_file_extensions
register_file_extension(ext, identifier, command, icon=icon, mode=self.menu.mode)
File "C:\Users\rclary\AppData\Local\spyder-6\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 75, in register_file_extension
winreg.SetValueEx(subkey, "DefaultIcon", 0, winreg.REG_SZ, icon)
PermissionError: [WinError 5] Access is denied
I get the same errors whether I run the installer as administrator or not, except the traceback file paths are C:\ProgramData\spyder-6...
instead. The first error appears to result because the spyder-6.AssocFilec
registry key was not created as expected. I'm puzzled why the second error occurs even when run from a cmd window with administrator privileges: why wasn't a PermissionError
raised when menuinst
was run from the installer?.
Conda Info
mamba version : 1.5.6
active environment : base
active env location : C:\Users\rclary\AppData\Local\spyder-6
shell level : 2
user config file : C:\Users\rclary\.condarc
populated config files : C:\Users\rclary\AppData\Local\spyder-6\.condarc
C:\Users\rclary\.condarc
conda version : 23.11.0
conda-build version : not installed
python version : 3.10.13.final.0
solver : libmamba (default)
virtual packages : __archspec=1=x86_64
__conda=23.11.0=0
__win=0=0
base environment : C:\Users\rclary\AppData\Local\spyder-6 (writable)
conda av data dir : C:\Users\rclary\AppData\Local\spyder-6\etc\conda
conda av metadata url : None
channel URLs : https://conda.anaconda.org/conda-forge/label/spyder_kernels_rc/win-64
https://conda.anaconda.org/conda-forge/label/spyder_kernels_rc/noarch
https://conda.anaconda.org/conda-forge/label/spyder_dev/win-64
https://conda.anaconda.org/conda-forge/label/spyder_dev/noarch
https://conda.anaconda.org/conda-forge/win-64
https://conda.anaconda.org/conda-forge/noarch
package cache : C:\Users\rclary\AppData\Local\spyder-6\pkgs
C:\Users\rclary\.conda\pkgs
C:\Users\rclary\AppData\Local\conda\conda\pkgs
envs directories : C:\Users\rclary\.conda\envs
C:\Users\rclary\AppData\Local\spyder-6\envs
C:\Users\rclary\AppData\Local\conda\conda\envs
platform : win-64
user-agent : conda/23.11.0 requests/2.31.0 CPython/3.10.13 Windows/10 Windows/10.0.19045 solver/libmamba conda-libmamba-solver/23.12.0 libmambapy/1.5.6
administrator : False
netrc file : None
offline mode : False
Conda Config
==> C:\Users\rclary\AppData\Local\spyder-6\.condarc <==
auto_update_conda: False
notify_outdated_conda: False
env_prompt: [spyder]({default_env})
channel_priority: flexible
channels:
- conda-forge/label/spyder_kernels_rc
- conda-forge/label/spyder_dev
- conda-forge
repodata_fns:
- repodata.json
==> C:\Users\rclary\.condarc <==
auto_activate_base: False
envs_dirs:
- ~/.conda/envs
channel_priority: flexible
channels:
- conda-forge/label/spyder_kernels_rc
- conda-forge
- defaults
show_channel_urls: True
conda-build:
root-dir: ~/.conda/conda-bld
Conda list
# packages in environment at C:\Users\rclary\AppData\Local\spyder-6:
#
# Name Version Build Channel
archspec 0.2.2 pyhd8ed1ab_0 conda-forge
boltons 23.1.1 pyhd8ed1ab_0 conda-forge
brotli-python 1.1.0 py310h00ffb61_1 conda-forge
bzip2 1.0.8 hcfcfb64_5 conda-forge
ca-certificates 2023.11.17 h56e8100_0 conda-forge
certifi 2023.11.17 pyhd8ed1ab_0 conda-forge
cffi 1.16.0 py310h8d17308_0 conda-forge
charset-normalizer 3.3.2 pyhd8ed1ab_0 conda-forge
colorama 0.4.6 pyhd8ed1ab_0 conda-forge
conda 23.11.0 py310h5588dad_1 conda-forge
conda-libmamba-solver 23.12.0 pyhd8ed1ab_0 conda-forge
conda-package-handling 2.2.0 pyh38be061_0 conda-forge
conda-package-streaming 0.9.0 pyhd8ed1ab_0 conda-forge
distro 1.9.0 pyhd8ed1ab_0 conda-forge
fmt 10.2.1 h181d51b_0 conda-forge
idna 3.6 pyhd8ed1ab_0 conda-forge
jsonpatch 1.33 pyhd8ed1ab_0 conda-forge
jsonpointer 2.4 py310h5588dad_3 conda-forge
krb5 1.21.2 heb0366b_0 conda-forge
libarchive 3.7.2 h313118b_1 conda-forge
libcurl 8.5.0 hd5e4a3a_0 conda-forge
libffi 3.4.2 h8ffe710_5 conda-forge
libiconv 1.17 hcfcfb64_2 conda-forge
libmamba 1.5.6 h3f09ed1_0 conda-forge
libmambapy 1.5.6 py310h04f2035_0 conda-forge
libsolv 0.7.27 h12be248_0 conda-forge
libsqlite 3.44.2 hcfcfb64_0 conda-forge
libssh2 1.11.0 h7dfc565_0 conda-forge
libxml2 2.12.4 hc3477c8_1 conda-forge
libzlib 1.2.13 hcfcfb64_5 conda-forge
lz4-c 1.9.4 hcfcfb64_0 conda-forge
lzo 2.10 he774522_1000 conda-forge
mamba 1.5.6 py310hd9d798f_0 conda-forge
menuinst 2.0.2 py310h00ffb61_0 conda-forge
openssl 3.2.0 hcfcfb64_1 conda-forge
packaging 23.2 pyhd8ed1ab_0 conda-forge
pip 23.3.2 pyhd8ed1ab_0 conda-forge
platformdirs 4.1.0 pyhd8ed1ab_0 conda-forge
pluggy 1.4.0 pyhd8ed1ab_0 conda-forge
pybind11-abi 4 hd8ed1ab_3 conda-forge
pycosat 0.6.6 py310h8d17308_0 conda-forge
pycparser 2.21 pyhd8ed1ab_0 conda-forge
pysocks 1.7.1 pyh0701188_6 conda-forge
python 3.10.13 h4de0772_1_cpython conda-forge
python_abi 3.10 4_cp310 conda-forge
reproc 14.2.4.post0 hcfcfb64_1 conda-forge
reproc-cpp 14.2.4.post0 h63175ca_1 conda-forge
requests 2.31.0 pyhd8ed1ab_0 conda-forge
ruamel.yaml 0.18.5 py310h8d17308_0 conda-forge
ruamel.yaml.clib 0.2.7 py310h8d17308_2 conda-forge
setuptools 69.0.3 pyhd8ed1ab_0 conda-forge
tk 8.6.13 h5226925_1 conda-forge
tqdm 4.66.1 pyhd8ed1ab_0 conda-forge
truststore 0.8.0 pyhd8ed1ab_0 conda-forge
tzdata 2023d h0c530f3_0 conda-forge
ucrt 10.0.22621.0 h57928b3_0 conda-forge
urllib3 2.1.0 pyhd8ed1ab_0 conda-forge
vc 14.3 hcf57466_18 conda-forge
vc14_runtime 14.38.33130 h82b7239_18 conda-forge
vs2015_runtime 14.38.33130 hcb4865c_18 conda-forge
wheel 0.42.0 pyhd8ed1ab_0 conda-forge
win_inet_pton 1.1.0 pyhd8ed1ab_6 conda-forge
xz 5.2.6 h8d14728_0 conda-forge
yaml-cpp 0.8.0 h63175ca_0 conda-forge
zstandard 0.22.0 py310h0009e47_0 conda-forge
zstd 1.5.5 h12be248_0 conda-forge
Additional Context
spyder-menu.json
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://schemas.conda.io/menuinst-1.schema.json",
"menu_name": "{{ DISTRIBUTION_NAME }} spyder",
"menu_items": [
{
"name": "Spyder 6",
"description": "Scientific PYthon Development EnviRonment",
"icon": "{{ MENU_DIR }}/spyder.{{ ICON_EXT }}",
"activate": false,
"terminal": false,
"command": [""],
"platforms": {
"win": {
"desktop": true,
"app_user_model_id": "spyder.Spyder",
"command": ["{{ PREFIX }}/pythonw.exe", "{{ PREFIX }}/Scripts/spyder-script.py"],
"file_extensions": [
"bat",
"c",
"cc",
"cfg",
"cl",
"cmd",
"cpp",
"css",
"cxx",
"desktop",
"diff",
"enaml",
"f",
"f03",
"f08",
"f2k",
"f77",
"f90",
"f95",
"for",
"h",
"h",
"hh",
"hpp",
"htm",
"html",
"hxx",
"inf",
"ini",
"ipy",
"ipynb",
"jl",
"js",
"json",
"m",
"md",
"nsh",
"nsi",
"patch",
"po",
"pot",
"pro",
"properties",
"pxd",
"pxi",
"py",
"pyw",
"pyx",
"reg",
"rej",
"rst",
"scss",
"session",
"txt",
"xml",
"yaml",
"yml"
]
},
"linux": {
"Categories": [
"Development",
"Science"
],
"command": ["{{ PREFIX }}/bin/spyder", "$@"],
"StartupWMClass": "Spyder",
"MimeType": [
"text/x-script.python",
"text/plain",
"text/html",
"text/xml",
"text/x-c",
"text/x-perl"
]
},
"osx": {
"precommand": "pushd \"$(dirname \"$0\")\" &>/dev/null",
"command": ["./python", "{{ PREFIX }}/bin/spyder", "$@"],
"link_in_bundle": {
"{{ PREFIX }}/bin/python": "{{ MENU_ITEM_LOCATION }}/Contents/MacOS/python"
},
"CFBundleName": "Spyder 6",
"CFBundleIdentifier": "org.spyder-ide.Spyder",
"CFBundleVersion": "6.0.0a4.dev152",
"CFBundleDocumentTypes": [
{
"CFBundleTypeName": "text document",
"CFBundleTypeRole": "Editor",
"LSHandlerRank": "Default",
"CFBundleTypeIconFile": "spyder.icns",
"LSItemContentTypes": [
"com.apple.applescript.text",
"com.apple.ascii-property-list",
"com.apple.audio-unit-preset",
"com.apple.binary-property-list",
"com.apple.configprofile",
"com.apple.crashreport",
"com.apple.dashcode.css",
"com.apple.dashcode.javascript",
"com.apple.dashcode.json",
"com.apple.dashcode.manifest",
"com.apple.dt.document.ascii-property-list",
"com.apple.dt.document.script-suite-property-list",
"com.apple.dt.document.script-terminology-property-list",
"com.apple.property-list",
"com.apple.rez-source",
"com.apple.scripting-definition",
"com.apple.structured-text",
"com.apple.traditional-mac-plain-text",
"com.apple.xcode.ada-source",
"com.apple.xcode.apinotes",
"com.apple.xcode.bash-script",
"com.apple.xcode.configsettings",
"com.apple.xcode.csh-script",
"com.apple.xcode.entitlements-property-list",
"com.apple.xcode.fortran-source",
"com.apple.xcode.glsl-source",
"com.apple.xcode.ksh-script",
"com.apple.xcode.lex-source",
"com.apple.xcode.make-script",
"com.apple.xcode.mig-source",
"com.apple.xcode.pascal-source",
"com.apple.xcode.strings-text",
"com.apple.xcode.tcsh-script",
"com.apple.xcode.yacc-source",
"com.apple.xcode.zsh-script",
"com.apple.xml-property-list",
"com.netscape.javascript-source",
"com.scenarist.closed-caption",
"com.sun.java-source",
"com.sun.java-web-start",
"net.daringfireball.markdown",
"org.khronos.glsl-source",
"org.oasis-open.xliff",
"public.ada-source",
"public.assembly-source",
"public.bash-script",
"public.c-header",
"public.c-plus-plus-header",
"public.c-plus-plus-source",
"public.c-source",
"public.case-insensitive-text",
"public.comma-separated-values-text",
"public.csh-script",
"public.css",
"public.delimited-values-text",
"public.dylan-source",
"public.filename-extension",
"public.fortran-77-source",
"public.fortran-90-source",
"public.fortran-95-source",
"public.fortran-source",
"public.html",
"public.json",
"public.ksh-script",
"public.lex-source",
"public.log",
"public.m3u-playlist",
"public.make-source",
"public.mig-source",
"public.mime-type",
"public.module-map",
"public.nasm-assembly-source",
"public.objective-c-plus-plus-source",
"public.objective-c-source",
"public.opencl-source",
"public.pascal-source",
"public.patch-file",
"public.perl-script",
"public.php-script",
"public.plain-text",
"public.python-script",
"public.rss",
"public.ruby-script",
"public.script",
"public.shell-script",
"public.source-code",
"public.tcsh-script",
"public.text",
"public.utf16-external-plain-text",
"public.utf16-plain-text",
"public.utf8-plain-text",
"public.utf8-tab-separated-values-text",
"public.xhtml",
"public.xml",
"public.yacc-source",
"public.yaml",
"public.zsh-script"
]
}
]
}
}
}
]
}
Hm, can you try with a leading period for the extensions? See example.
"It works on CI", but CI runs as administrator by default, so we might need to adjust something. "Open With" has not been added per se, as it requires some extra registry keys.
@mrclary did you have a chance to take a look at the workaround?
@jaimergp, sorry, I have not yet had a chance to look at it.
The short of it
I suspect that an error occurs on install after the first item in the file extension list is handled resulting in no other extensions being handled, but the shortcut is produced. On uninstall, an error results due to the missing expected AssocFiles.
The long of it
So I tried using menuinst
in a standard conda environment.
(base) C:\Users\rclary>mamba create -n spyder6_test -c conda-forge/label/spyder_dev -c conda-forge/label/spyder_kernels_rc spyder=6.0.0a4
This version of Spyder does not have file extensions listed in the spyder-menu.json
file and the shortcut is created without issue. I can also uninstall it without issue.
(base) C:\Users\rclary>set bp=C:\Users\AppData\Local\miniforge3
(base) C:\Users\rclary>set tp=%bp%\envs\spyder6_test
(base) C:\Users\rclary>set menu=%tp%\Menu\spyder-menu.json
(base) C:\Users\rclary>python -c "from menuinst.api import remove; remove(r'%menu%', target_prefix=r'%tp%', base_prefix=r'%bp%')"
However, I get the following errors after modifying spyder-menu.json
to include two file extensions.
spyder-menu.json
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://schemas.conda.io/menuinst-1.schema.json",
"menu_name": "{{ DISTRIBUTION_NAME }} spyder",
"menu_items": [
{
"name": "Spyder 6 ({{ ENV_NAME }})",
"description": "Scientific PYthon Development EnviRonment",
"icon": "{{ MENU_DIR }}/spyder.{{ ICON_EXT }}",
"activate": false,
"terminal": false,
"command": [""],
"platforms": {
"win": {
"desktop": true,
"app_user_model_id": "spyder.Spyder",
"command": ["{{ PREFIX }}/pythonw.exe", "{{ PREFIX }}/Scripts/spyder-script.py"],
"file_extensions": [
".py",
".pyw"
]
},
"linux": {
"Categories": [
"Development",
"Science"
],
"command": ["{{ PREFIX }}/bin/spyder", "$@"],
"StartupWMClass": "Spyder"
},
"osx": {
"precommand": "pushd \"$(dirname \"$0\")\" &>/dev/null",
"command": ["./python", "{{ PREFIX }}/bin/spyder", "$@"],
"link_in_bundle": {
"{{ PREFIX }}/bin/python": "{{ MENU_ITEM_LOCATION }}/Contents/MacOS/python"
},
"CFBundleName": "Spyder 6",
"CFBundleIdentifier": "org.spyder-ide.Spyder",
"CFBundleVersion": "6.0.0a4"
}
}
}
]
}
(base) C:\Users\rclary>python -c "from menuinst.api import install; install(r'%menu%', target_prefix=r'%tp%', base_prefix=r'%bp%')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\utils.py", line 426, in wrapper_elevate
return func(
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\api.py", line 62, in install
paths += menu_item.create()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 167, in create
self._register_file_extensions()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 365, in _register_file_extensions
register_file_extension(ext, identifier, command, icon=icon, mode=self.menu.mode)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 75, in register_file_extension
winreg.SetValueEx(subkey, "DefaultIcon", 0, winreg.REG_SZ, icon)
PermissionError: [WinError 5] Access is denied
HKCU\Software\Classes\spyder-6-spyder6-test.AssocFile.py
appears in the registry, but not HKCU\Software\Classes\spyder-6-spyder6-test.AssocFile.pyw
.
And attempting to uninstall:
(base) C:\Users\rclary>python -c "from menuinst.api import remove; remove(r'%menu%', target_prefix=r'%tp%', base_prefix=r'%bp%')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\utils.py", line 426, in wrapper_elevate
return func(
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\api.py", line 84, in remove
paths += menu_item.remove()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 173, in remove
self._unregister_file_extensions()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 375, in _unregister_file_extensions
unregister_file_extension(ext, identifier, mode=self.menu.mode)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 88, in unregister_file_extension
_reg_exe("delete", fr"{root_str}\Software\Classes\{identifier}")
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 25, in _reg_exe
return logged_run(["reg.exe", *args, "/f"], check=True)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\utils.py", line 470, in logged_run
process.check_returncode()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\subprocess.py", line 457, in check_returncode
raise CalledProcessError(self.returncode, self.args, self.stdout,
subprocess.CalledProcessError: Command '['reg.exe', 'delete', 'HKCU\\Software\\Classes\\spyder-6-spyder6-test.AssocFile.pyw', '/f']' returned non-zero exit status 1.
HKCU\Software\Classes\spyder-6-spyder6-test.AssocFile.py
is removed from the registry, but there is the error for .pyw
.
If I only have one extension in the list, the install produces the same error, although the AssocFile is produced. The uninstall does not produce an error. So, I suspect that the error occurs on install after the first extension in the list is handled resulting in no other extensions being handled, but the shortcut is produced nonetheless. Then, on uninstall, the error is a result of the missing expected AssocFiles.
Looks like the problem is at:
https://github.com/conda/menuinst/blob/db528854422d765d9423eb7c705e06b0c7ade905/menuinst/platforms/win_utils/registry.py#L73-L76
So maybe it works if you remove the icon
entry from the JSON. I'll check where that permissions issue is coming from and add tests with icons. I see several things to fix the code with:
@jaimergp, with menuinst=2.1.1
I no longer have the issues I described in my previous comment: https://github.com/conda/menuinst/issues/185#issuecomment-1982536505 👏🏼. I can add/remove the shortcut without errors and the registry entries are added/removed as expected.
The only issue that remains is that the file type association in context menus appears as Python instead of Spyder (both name and icon). Nevertheless, associating with "Python" does, in fact, open the file in Spyder. Perhaps this is a result of the shortcut target using pythonw.exe
instead of spyder.exe
? I know we've discussed in the past regarding executable targets causing cmd windows to open, which is why I target pythonw.exe
instead.
@jaimergp, actually there is still an issue with the registry when removing an environment. For example
(base) C:\Users\rclary>mamba remove -n spy6b3d8 --all
Remove all packages in environment C:\Users\rclary\.conda\envs\spy6b3d8:
Preparing transaction: done
Verifying transaction: done
Executing transaction: | menuinst Exception
Traceback (most recent call last):
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\conda\gateways\disk\create.py", line 261, in make_menu
menuinst.install(
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\api.py", line 168, in _install_adapter
_api_remove(metadata, target_prefix=prefix, **kwargs)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\utils.py", line 426, in wrapper_elevate
return func(
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\api.py", line 84, in remove
paths += menu_item.remove()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 207, in remove
self._unregister_file_extensions()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win.py", line 457, in _unregister_file_extensions
unregister_file_extension(ext, identifier, mode=self.menu.mode)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 89, in unregister_file_extension
_reg_exe("delete", fr"{root_str}\Software\Classes\{identifier}")
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\platforms\win_utils\registry.py", line 26, in _reg_exe
return logged_run(["reg.exe", *args, "/f"], check=True)
File "C:\Users\rclary\AppData\Local\miniforge3\lib\site-packages\menuinst\utils.py", line 470, in logged_run
process.check_returncode()
File "C:\Users\rclary\AppData\Local\miniforge3\lib\subprocess.py", line 457, in check_returncode
raise CalledProcessError(self.returncode, self.args, self.stdout,
subprocess.CalledProcessError: Command '['reg.exe', 'delete', 'HKCU\\Software\\Classes\\spyder-6-spy6b3d8.AssocFile.bat', '/f']' returned non-zero exit status done
The registry key is removed, so perhaps it is trying to delete it again and it's no longer there?
Also, FYI, conda env remove -n spy6b3d8
removes the environment, but not the shortcut or registry keys and there is no error reported. Only conda remove -n spy6b3d8 --all
removes the menuinst
shortcut, registry keys, and the environment, but with the reported error.
Also, FYI,
conda env remove -n spy6b3d8
removes the environment, but not the shortcut or registry keys and there is no error reported.
Yes, this is a known issue: https://github.com/conda/conda/issues/11092.
I'll look into the other reports, thanks for giving it a try!
Edit: Found these resources. Writing them down here for future reference:
-
ProgIDs attributes might be useful for the application name overrides. I think we were setting the icon right (assuming it's a single-icon .ico file, we don't need the
,index
syntax). I'm not sure how we can add a custom text resource without compiling a custom DLL yet. - Some practical examples
Apparently Windows wants us to use "indirect strings" for those Progids attributes. We can't just put the text directly there.
Instead, we are asked to bundle the custom strings in a resource binary (.rsrc
section in a PE file). These files are usually written by passing an XML file to rc.exe
(part of the Windows SDK). We can't depend on that or expect it to be installed (too big, compiled, non-redistributable).
Writing a PE file from scratch is technically possible with pefile
, pe-tools
or lief
; the former is preferred because it's lighter, but it will take a lot of experimentation to find out how the strings look like in the final file. lief
has some resource handling convenience wrappers that might make it easier but it's heavier as a dependency that will be added to conda
...
Huh, turns out at least one more person in the world has looked into this and reported that Windows 10 does support raw strings without the PE indirection. That simplifies things drastically. I'll open a PR once I can push to the repo.
@mrclary, is there a chance you can try https://github.com/conda/menuinst/pull/225 locally?
Perhaps this is a result of the shortcut target using
pythonw.exe
instead ofspyder.exe
? I know we've discussed in the past regarding executable targets causing cmd windows to open, which is why I targetpythonw.exe
instead.
I'm wondering about this now. spyder.exe
is essentially a renamed launcher cli-64.exe
launcher, as shipped in conda. conda-build has that launcher but also a gui-64.exe
variant. Maybe if you copy the gui one as spyder.exe
the window problem is gone? The file is not used anywhere in the conda-build code these days, though, but it has to have a purpose, doesn't it? :D
I'm wondering about this now.
spyder.exe
is essentially a renamed launchercli-64.exe
launcher, as shipped in conda. conda-build has that launcher but also agui-64.exe
variant.
I think you are correct; it is exactly just a renamed launcher designed to run a file of its own name <name>-script.pyw
https://github.com/conda/conda-build/blob/2ba431f352ab289347d3676865a4fee898946ff1/conda_build/convert.py#L572
Maybe if you copy the gui one as
spyder.exe
the window problem is gone? The file is not used anywhere in the conda-build code these days, though, but it has to have a purpose, doesn't it? :D
Indeed, doing as you suggest and replacing the shortcut target results in Spyder launching without a cmd window 😄. However, the spyder.exe
icon is now a generic Windows executable icon rather than the Python executable icon. So we'd still have to figure out how to change the icon for spyder.exe
🤷🏼 (https://github.com/conda/menuinst/pull/225#issuecomment-2205565379). I wonder how python.exe
gets its icon...
Notably, conda-build
doesn't currently offer a mechanism for choosing gui-64.exe
over cli-64.exe
, but I suppose this can be worked around in the bld.bat
script of the feedstock (including renaming spyder-script.py
to spyder-script.pyw
). I think I will implement this for Spyder and hopefully this feature could be added to conda-build
sometime in the future 🤞🏼.
Notably,
conda-build
doesn't currently offer a mechanism for choosinggui-64.exe
overcli-64.exe
, but I suppose this can be worked around in thebld.bat
script of the feedstock (including renamingspyder-script.py
tospyder-script.pyw
). I think I will implement this for Spyder and hopefully this feature could be added toconda-build
sometime in the future 🤞🏼.
Nope, this work-around does not work. Apparently, conda-build
populates the Scripts
directory after bld.bat
is run. I can copy gui-64.exe
, but it gets overwritten by the cli-64.exe
, and spyder-script.py
is not found when attempting to rename it. See https://github.com/mrclary/spyder-feedstock/blob/dd592ab21543650df6f85efa21bcd3cdd77819e9/recipe/bld.bat
Pity, that's a current noarch: python
limitation. You are going to need a non-noarch variant build (even if it's just for the shortcut and not Spyder itself).
We could add the feature in conda-build + conda but only recent versions would be compatible and we are looking at a September release the earliest.
Ah, it's already non-noarch. What if you copy gui-64.exe
manually in $PREFIX/Scripts
as spyder.exe
and write the spyder-script.pyw
file manually on Windows (instead of via conda-build features)?. It's just boilerplate after all:
# -*- coding: utf-8 -*-
import re
import sys
from YOUR.MODULE import YOUR_FUNCTION
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(YOUR_FUNCTION())
What if you copy
gui-64.exe
manually in$PREFIX/Scripts
asspyder.exe
and write thespyder-script.pyw
file manually on Windows (instead of via conda-build features)?.
🤔 spyder.exe
is what gets overwritten, but I could copy gui-64.exe
and write spyder-script.pyw
, then in the post-link script overwrite spyder.exe
with gui-64.exe
and delete spyder-script.py
.
Yes, my suggestion is to not generate the entry point in Windows and instead do it by hand in the build script. This way you get rid of the post-link / pre-unlink scripts.
@jaimergp, I think this issue is resolved by conda/menuinst#225.
Thanks!