Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interact with apps installed on Windows using WSL2

I got my WSL2 up and running. On Windows level I installed node.js and now I want to run npm install snowflake-sdk from Ubuntu level. Terminal returns -bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory while PowerShell works fine.

Question is: is it possible to interact with Windows level installed applications using WSL2's terminal?

like image 602
marcin2x4 Avatar asked Oct 20 '25 15:10

marcin2x4


2 Answers

Note:

  • The more typical scenario is to install Node.js and npm on the Linux side, as per the official instructionsThanks, SeaDude. If you then need to call from Windows, you can use
    wsl npm ..., but note that cross-file-system calls are generally discouraged in WSL2.

harzvor's helpful answer provides good background information.

It is possible to make calling npm from a Windows-installed Node.js copy from WSL2 work, though it's not obvious and a bit cumbersome - though you could wrap the workaround in a custom function or script:

# From WSL2; note the required use of '.exe'
node.exe 'c:/Program Files/nodejs/node_modules/npm/bin/npm-cli.js' install snowflake-sdk

The above, which relies on Node.js being installed in its default location on Windows, calls npm indirectly, using essentially the same technique that the CLI entry point on Windows, the npm.cmd batch file, uses.

Note:

  • In order to target a Windows executable from WSL, you must include the filename extension explicitly, such as node.exe rather than node.

  • Without it, e.g. with npm, the Linux subsystem looks for an extension-less file by that name in the $PATH folders, which does not work.

    • Such a file actually does exist even on Windows, but it is a shebang-based script designed for Unix-like platforms, and basically just dead weight in a Windows installation; the Linux subsystem still tries to execute it, but fails, because it uses CRLF (\r\n) newlines rather than the expected LF-only (\n) newlines. As a result, the unexpected CR that follows #!/bin/sh (represented as ^M in the error message) is considered a part of the executable path, so the invocation fails.[1]

    • Even fixing that problem manually (converting to LF-only newlines) doesn't help, however, because of how the shell script constructs the full path to the npm-cli.js entry point: it expresses it as an UNC path that tries to target the Windows file-system location via the WSL file-system - e.g.,
      \\wsl$\Ubuntu-20.04\mnt\c\... - which is explicitly disallowed.[2]

  • Calling the batch file, npm.cmd, explicitly, doesn't work either - neither directly nor with cmd.exe /c npm.cmd ...:

    • Direct invocation of a *.cmd file fails obscurely - not sure if that's a bug as of Windows 10 20H2.
    • Via cmd.exe /c it fails too, because cmd.exe doesn't support UNC paths as the current directory and the WSL2-internal current directory path is invariably expressed as one (e.g., \\wsl$\Ubuntu-20.04\home\jdoe\project\some-project).
      cmd.exe defaults to the Windows directory in this case, so installation of packages to the current WSL directory('s project) won't work).
  • Providing the full Windows-native path to the npm CLI's main .js file to node.exe, as shown above, works as expected, since Node.js seems to otherwise be handling UNC paths that refer to WSL2 file-system directories and files, such as the calling WSL2's shell current directory, properly.


[1] On Ubuntu 20.04, the CR in the shebang line itself no longer seems to be a problem, but the CRs in the remaining lines still are, so the invocation still fails, even more obscurely, which error messages such as : not foundram Files/nodejs/npm: 3:.

[2] The reason is that the Linux dirname utility is used to determine the shell script's own directory in order to determine npm-cli.js's full path, and this utility by design operates from the perspective of the Linux file-system, which ends up expressing the script's Windows file-system location in this indirect, unsupported manner.

like image 148
mklement0 Avatar answered Oct 22 '25 05:10

mklement0


> is it possible to interact with Windows level installed applications using WSL2's terminal?

Yes, you can run notepad.exe from WSL and it will open Notepad in Windows.

More documentation: https://learn.microsoft.com/en-us/windows/wsl/interop#run-windows-tools-from-linux

Solving the NPM issue

If I try running npm -v in WSL, I get an error about it not being able to find a file:

PS C:\Users\harvey> bash
harvey@harvey-w10x64-defiance:/mnt/c/Users/harvey$ npm -v
internal/modules/cjs/loader.js:968
  throw err;
  ^

Error: Cannot find module 'C:\mnt\c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
    at Function.Module._load (internal/modules/cjs/loader.js:841:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

The path to the file is mostly correct but it has appended C:\mnt to it.

I managed to get around this by running npm by giving Node the path to the npm-cli.js file.

You can run:

node.exe \c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -v

But that runs into the same error.

I then tried this:

PS C:\Users\harvey> bash
harvey@harvey-w10x64-defiance:/mnt/c/Users/harvey$ cd "/mnt/c/Program Files/nodejs/node_modules/npm/bin"
harvey@harvey-w10x64-defiance:/mnt/c/Program Files/nodejs/node_modules/npm/bin$ ../../../node.exe npm-cli.js -v
6.14.6

From here I was finally able to get some output from the NPM CLI.

From here I can install the package but it will likely be installed in the wrong location.

I couldn't seem to get npm working from anywhere in the filesystem. This may be a limitation with NPM. Perhaps if you try messing with your path env vars, you can get it to work?

like image 20
harvzor Avatar answered Oct 22 '25 05:10

harvzor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!