Closed bradwilson closed 3 years ago
With Remote WSL isntalled, there's comes the concept of remote hosts, where extensions can be installed either locally or/and on remote. Running code --install-extension
in a WSL shell should install the extension on the remote side, which we don't support (yet) via CLI.
To install a an extension on the windows side, you need to run code --install-extension
in a windows command prompt.
(Experimental duplicate detection) Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:
The fact that code --install-extension
works just fine to install extensions to the Windows side before your extension is installed, means to me that code --install-extension
should continue to install extensions to the Windows side even after your extension is added, for consistency purposes (it doesn't make sense that adding your extension would change the behavior).
Adding an additional flag to code --install-extension
when "Remote - WSL" is installed to install Linux-side extensions would also be a nice to have feature, but that's not actually what I'm asking for. I just want you to un-break this behavior that my Ansible playbooks depend on. 😄
@bradwilson To install extensions on Windows 'the old way', you need to call the WIndows code command (code.cmd), not code.sh.
I first thought you wanted the WSL code command to install extensions in WSL. That is possible when in the remote integrated terminal: https://github.com/microsoft/vscode-remote-release/issues/2589
@aeschli You misread my issue and then closed it based on your misunderstanding.
@bradwilson Yes, I'm a bit confused. Can you clarify what your request is?
code --install-extension
in a Windows command prompt (running code.cmd
) will install extensions in the Windows side. I tested that this works regardless if the Remote WSL
extension is installed or not.code --install-extension
in a WSL shell (running code.sh
) will
Remote WSL
extension installed install extensions in the Windows side.Remote WSL
extension not do anything. If it were to do something it should install an extension on the WSL side.My suggestion was that installing an extension on the Windows side was what you want, run code.cmd
. (from a WSL shell: cmd.exe /c "code.cmd --install-extension ..."
)
It's quite simple:
code
command in WSL.code
command in WSL.Something in this extension breaks the way code
works such that I can no longer install extensions.
Your proposed workaround is "don't do that", except that's sort of irrelevant. You've broken something that works, and just because you didn't break something else (running code
from Windows) isn't the point.
If what you're really asking is "why do you want to run code
from WSL?", the answer is: I automate the standing up of my Linux-based development environment with Ansible scripts. Obviously these work fine on native Linux; they also work fine within WSL, right up to the moment where "Remote - WSL" is installed at which point my automation is now broken.
Here's an example of one such script:
- name: .NET Core (VS Code)
hosts: 127.0.0.1
connection: local
tasks:
- name: Install VS Code Extensions
command: code --install-extension {{ item }}
args:
creates: ~/.vscode/extensions/{{ item }}-*/package.json
loop:
- formulahendry.dotnet-test-explorer # .NET Core Test Explorer
- k--kato.docomment # C# XML Documentation Comments
- ms-dotnettools.csharp # C#
The end result is that once the Ansible script installs "Remote - WSL" (by way of installing ms-vscode-remote.vscode-remote-extensionpack
), then Ansible is immediately no longer able to install any new extensions into VSCode. (There's a small amount of unintended irony that I install "Remote - WSL" with the feature which you then immediately break. 😂)
If you choose not to fix this, then that's your decision, but your suggested workaround is wholly unacceptable to my usage. I also don't think you should have the right to decide to arbitrarily break a built-in feature which was already working, but that's my personal interpretation.
In this particular case the problem is that code.cmd (the Windows command shell script) handles the functionality to install extensions. That functionality is still there and usable, even with Remote-WSL installed. However, once Remote-WSL is added, code
from the Linux shell now gets code.sh
instead of code.cmd
, and code.sh
doesn't have that functionality, because it's for launching via the Remote-WSL server instead of the Windows side.
Explicitly calling code.cmd
, as was mentioned earlier, still works and is probably the workaround you need. However, you have to call it via cmd.exe, because otherwise bash tries to parse it as a shell script.
$ /mnt/c/Windows/System32/cmd.exe /C "C:\Program Files\Microsoft VS Code\bin\code.cmd" --install-extension ms-vscode.vscode-node-azure-pack
Installing extensions...
You could key off one of the environment variables WSL sets by default to have an ansible playbook that will work in either location:
- name: .NET Core (VS Code)
hosts: 127.0.0.1
connection: local
tasks:
- include_tasks: set_vscode_facts.yml
- name: Install VS Code Extensions
command: "{{ vscode_command }} --install-extension {{ item }}"
args:
creates: "{{ vscode_extensions }}/{{ item }}-*/package.json"
loop:
- formulahendry.dotnet-test-explorer # .NET Core Test Explorer
- k--kato.docomment # C# XML Documentation Comments
- ms-dotnettools.csharp # C#
set_vscode_facts.yml
:
- name: Set VS Code facts (Linux)
set_fact:
vscode_command: code
vscode_extensions: ~/.vscode/extensions
when: "'WSL_INTEROP' not in ansible_env"
- name: Set VS Code facts (WSL)
set_fact:
vscode_command: '/mnt/c/Windows/System32/cmd.exe /C "C:\Program Files\Microsoft VS Code\bin\code.cmd"'
vscode_extensions: /mnt/c/Users/$USER/.vscode/extensions
when: "'WSL_INTEROP' in ansible_env"
@phealy Attempting to validate this analysis, I feel like it's either incorrect (or the description is misleading, perhaps in an attempt at simplification). I need to get a Windows machine w/ VS Code on it (without any extensions installed yet) to validate my analysis, because I can't assume that the act of installing "Remote - WSL" didn't replace the default code
Bash script with one that's remote-aware. But my initial swag through shows me that at no time does code
in WSL ever invoke code.cmd
, whether you have "Remote - WSL" installed or not. The shift point appears to be between either invoking a shell script that resides inside the "Remote - WSL" installation folder vs. directly invoking electron.exe
to run the cli.js
script that's part of VS Code. (This is also what code.cmd does on the Windows side, but it's much simpler since it just assumes you're running on Windows and doesn't do any WSL or Remote detection logic.)
So the differences come down the features that are implemented in cli.js
but not in wslCode.sh
. Those differences can be summarized as: installing "Remote - WSL" (which causes code
to run wslCode.sh
instead of cli.js
) removes all the extension management commands. This is fundamentally my complaint: wslCode.sh
could absolutely be updated to support the handful of command line switches simply by falling back to running cli.js
(just like code
does) when it detects that the user has asked to perform one of the extension management commands. This is fundamentally my ask: don't take away functionality that users might be depending on.
As for your suggested workaround, there are some assumptions in it:
C:\Windows
C:\Program Files
rather than C:\Users\<username>\AppData\Local
)C:\Users\<username>\AppData\Local
)Because of this, I would describe this more as a "temporary" fix, and not a legitimate long-term workaround.
I agree - this could certainly be cleaned up. In fact, you can probably fix a number of those assumptions by just assuming the user has a sane PATH, which you were doing anyway by just running code. However, this assumes that the user is using a WSL distribution that packages the WSL utilities.
cmd.exe /c "echo %APPDATA%"
which code
via wslpath: wslpath -w "$(which code)"
I'm not on the VS Code Remote team, I just happened to come across this and thought I could offer a suggestion for a fix that would let you keep going.
In 1.53, code.sh
with Remote-WSL installed now also supports install/uninstall-extension
and list-extension
. But, it will install/list extensions only the remote/WSL side.
I understand that this is not the direction you wanted. But we believe is what users that work in WSL with the Remote-WSL extension need and expect.
We are thinking of adding a --local
flag to enable installing extensions locally as well. If that's something that would like to have, lets create a separate request and continue the discussion there.
Sorry for hijacking your bug request and turning it into a feature request for something you didn't want.
Sounds like I should just work to adapt @phealy's workaround.
I am running WSL 2 (from the 20H1 Slow Ring, build 19033), and I have VS Code installed on the Windows side. I have noticed that adding
Remote - WSL
breaks some of the WSL-to-Windows communication paths, namely the ability to invokecode --install-extension
from WSL and have it install the extension in Code for Windows.Note that this functionality works fine without "Remote - WSL" installed; it's only the installation of the remote extension inside of VS Code that breaks the communication.
Without WSL - Remote:
code --install-extension
from WSL correctly installs the extension on the Windows side of VS Code (without any UI popup)With WSL - Remote:
code --install-extension
incorrectly pops up the VS Code UI (does not open any folder, just pops up the UI) and the extension is not installed.