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

[BUG] Any other Node installation takes precedence over the NVM Desktop version (user PATH always comes after system PATH on Windows) #131

Open
iki opened this issue Oct 20, 2024 · 9 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@iki
Copy link

iki commented Oct 20, 2024

Describe the bug

When installing on Windows with Node already installed (globally, or using Volta), there's no way to prioritize NVM Desktop, because the shims are placed in %UserProfile%\.nvmd\bin and user PATH always comes after system PATH on Windows.

To Reproduce
Steps to reproduce the behavior:

  1. Install NVM Desktop on Windows with Node.js already installed (globally, or using Volta)
  2. Install any Node version using NVM Desktop
  3. [ISSUE] Run where node -> It still points to the original installation of Node

Expected behavior
User should be able to prioritize NVM Desktop in PATH.

Possible solution could be putting shims to system PATH %ProgramFiles%\NVM Deskop\bin instead, similarly to how Volta puts them to to %ProgramFiles%\Volta. It seems like a good idea anyway, as there's no need for each user to have their own copy of the shims.

Desktop:

  • OS: Windows 11 23H2 Home 10.0.22635.4367
  • Arch: x64
  • NVM Desktop Version: 4.0.2
@iki iki added the bug Something isn't working label Oct 20, 2024
@iki
Copy link
Author

iki commented Oct 20, 2024

Tested Workaround / Proof of concept:

  1. Move the shims sudo mv "%UserProfile%\.nvmd\bin" "%ProgramFiles%\NVM Deskop"
  2. Insert them to global system PATH setx /m path "%ProgramFiles%\NVM Deskop\bin;%PATH%"
  3. Restart your shell/terminal
  4. Verify where node -> Outputs <ProgramFiles>\NVM Deskop\bin\node.exe
  5. Test node --version inside and outside a project directory -> Works as expected

@1111mp
Copy link
Owner

1111mp commented Oct 21, 2024

On Windows platforms, use the nsis script to set system environment variables during installation:

ExecWait '$INSTDIR\resources\envpath.exe add "$1"' ; put the path in quotes because of possible spaces

Here is the relevant code for envpath:

pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
    let env = hklm.open_subkey_with_flags(
        r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
        KEY_READ | KEY_WRITE,
    )?;
    let env_path: String = env.get_value("PATH").unwrap_or_default();

    // if not exist then add
    if config.query == "add" && !env_path.split(";").any(|p| p == config.path) {
        let new_env_path = format!("{};{}", env_path, config.path);
        env.set_value("PATH", &new_env_path)?;
    }

    // remove from path
    if config.query == "remove" {
        let new_env_path = env_path
            .split(";")
            .filter(|p| *p != config.path)
            .collect::<Vec<&str>>()
            .join(";");
        env.set_value("PATH", &new_env_path)?;
    }

    Ok(())
}

It is designed to always be added to the end of the system environment variables, not the beginning.
image

I'm not sure if raising its priority in the environment variables will make some users feel unfriendly. Perhaps this can be discussed first, and I will deal with this issue after confirming that it is acceptable.

@iki
Copy link
Author

iki commented Oct 21, 2024

@1111mp raising the priority by default is not needed. The important part is allowing user to do so if he has multiple Node installs, e.g. Node installed already from the official Node installer, or by Volta.

The issue is, that it is not possible when shims are in user PATH, because Node/Volta are in system PATH and system PATH always precedes user PATH on Windows.

Moving the shims to "%ProgramFiles%\NVM Deskop\bin" allows the user to put them ahead of previous Node installs in system PATH.

@1111mp
Copy link
Owner

1111mp commented Oct 21, 2024

I think you just need to make sure that "%UserProfile%.nvmd\bin" has a higher priority than "%ProgramFiles%\Volta" in the system environment variable PATH (that is, it is located in the front).

  • Right-click "This PC" (or "My Computer") and select “Properties”.
  • Click on “Advanced system settings” on the left.
  • Click the “Environment Variables” button.
  • In the “System variables” section, find and select Path, then click “Edit” to view its values.
    image

@iki
Copy link
Author

iki commented Oct 21, 2024

Ah, you're correct, %UserProfile%\.nvmd\bin can be placed to system PATH as well.

Many thanks for your help and for a great tool🔥

@iki iki closed this as completed Oct 21, 2024
@iki
Copy link
Author

iki commented Oct 23, 2024

Hi @1111mp

I tested the C:\Users\<user>\.nvmd\bin added to system PATH by NVM Desktop once again, as user folder in system PATH is quite unusual.

There's issue on Windows desktops with multiple users: Only the user who installed NVM Desktop can use it, while others have an inaccessible path in system PATH.

It's reproducible on any Windows station by creating second account and login with it. I just did it on my too and the path is inaccessible.

The multiple users Windows desktop is common case with desktops/virtuals in organizations, e.g. for developers in customer organization, or when connecting via VPN there.

I also tried working around by adding %UserProfile%\.nvmd\bin to system PATH instead, but it doesn't work either. After clean start, it resolves to C:\WINDOWS\system32\config\systemprofile\.nvmd\bin in environment PATH variable.

I didn't see any other software using user folder in system PATH so far and I'm not aware of any way to make it work.

The common solution is the one suggested in description above: Use <NVM Desktop installation folder>\bin for shims and put that to system PATH if it's outside %UserProfile% (default), or to user PATH when user installed to a custom location that happens to be inside %UserProfile%.

WDYT?

@iki iki reopened this Oct 23, 2024
@1111mp
Copy link
Owner

1111mp commented Oct 24, 2024

I think this is expected behavior as it helps maintain privacy as one of the accounts. If an account has administrator privileges, then the account can access files in the %UserProfile% directory of other users. But it should be done with caution to respect user privacy.

Windows Installer
The Windows installer will unpack all of the binaries into Program Files\Volta and add that folder to the System Path environment variable. It will also create the shims for the following tools in that directory:

node
npm
npx
yarn

Shim Directory
The Volta shim directory needs to be added to the PATH as well, so that the shims will work as expected as well. The shim directory is at $VOLTA_HOME/bin (%VOLTA_HOME%\bin on Windows), where VOLTA_HOME is defaulted to:

~/.volta on Unix
%LOCALAPPDATA%\Volta on Windows
Updating the PATH can be managed manually, if desired, or you can call volta setup (as the official installers do, described above).

Through investigation, it was found that the default location of Volta's shim directory on Windows is %LOCALAPPDATA%\Volta, which also exists in the user directory.

Custom Volta Home (Optional)
If you wish to use a different directory for the Volta data than the default VOLTA_HOME listed in the previous section, you need to set the environment variable VOLTA_HOME to that directory. If that is set, then volta setup will still work correctly for a custom data directory.

However, Volta does provide the function of modifying the shim directory. Perhaps we should also add the same functionality to allow users to decide which directory the shims are stored in.

@iki
Copy link
Author

iki commented Oct 29, 2024

Yes, Volta uses %ProgramFiles%\Volta in system PATH for base node/npm/npx/yarn/pnpm shim and %LocalAppData%\Volta in user PATH for shims of npm packages installed globally (for any of the Volta managed Nodes).

Putting the base node/npm/npx/yarn/pnpm shims in system PATH allows to prioritize them before default Node installation in PATH. That's not possible with base shims in user PATH as Windows always put system PATH before user PATH.

On contrary, putting global npm packages shims in user PATH allows each user to have their own set of global packages installed and with cli runnable from PATH.

It's quite common setup and NVMD could use it too IMO. WDYT?

@1111mp
Copy link
Owner

1111mp commented Oct 29, 2024

OK, I will implement this feature in the next version. (It may take a while...) 🌹

@1111mp 1111mp added the enhancement New feature or request label Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants