explorer.exe doesn't open correct folder when ran programmatically inside WSL

Viewed 200

I'm trying to open explorer.exe from a Node.js script running inside WSL Ubuntu 20.04. The issue I've encountered is that explorer.exe never opens the folder I'd like it to. Instead of WSL user's home directory it opens my Windows user's Documents folder. What should I do to make explorer.exe open the folder I want?

Here's what I've tried:

The script first defines a function execShellCommand that promisifies exec. Then self-executing function first converts process.env.HOME to a Windows path with wslpath. Then it executes explorer.exe with the converted path as a parameter.

#!/usr/bin/node

const execShellCommand = async cmd => {
  const exec = require('child_process').exec
  return new Promise((resolve, reject) => {
    exec(cmd, (error, stdout, stderr) => {
      if (error) {
        console.warn(error)
      }
      resolve(stderr ? stderr : stdout)
    })
  })
}

;(async () => {
  const path = await execShellCommand(`wslpath -w "${process.env.HOME}"`)
  console.log({ path })
  await execShellCommand(`explorer.exe ${path}`)
})()

The output I get when I run my script in WSL

$ ./script.js 
{ path: '\\\\wsl$\\Ubuntu-20.04\\home\\user\n' }
Error: Command failed: explorer.exe \\wsl$\Ubuntu-20.04\home\user


    at ChildProcess.exithandler (child_process.js:308:12)
    at ChildProcess.emit (events.js:315:20)
    at maybeClose (internal/child_process.js:1048:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5) {
  killed: false,
  code: 1,
  signal: null,
  cmd: 'explorer.exe \\\\wsl$\\Ubuntu-20.04\\home\\user\n'
}

explorer.exe does run regardless of the error shown in the output. The weird part is that if I run the same command my script tries to run (explorer.exe \\\\wsl$\\Ubuntu-20.04\\home\\user\n) directly in WSL terminal explorer.exe does open the folder I want it to. Trimming the new line at the end of the path doesn't help.

1 Answers

I think you have to do some additional escaping on the backslashes that are produced by wslpath. The code below works for me, meaning it opens the correct directory in Windows Explorer.

Note: it does still throw the error you mentioned, which I think is due to the way node exits rather than anything wrong w/the execution of explorer.exe; I'm not a node expert by any stretch.

#!/usr/bin/node

const execShellCommand = async cmd => {
          const exec = require('child_process').exec
          return new Promise((resolve, reject) => {
                      exec(cmd, (error, stdout, stderr) => {
                                    if (error) {
                                                    console.warn(error)
                                                  }
                                    resolve(stderr ? stderr : stdout)
                                  })
                    })
}

;(async () => {
          let path = await execShellCommand(`wslpath -w "${process.env.HOME}"`)
          console.log("before", {path});
          path = path.replace(/\\/g,"\\\\");
          console.log("after", {path});
          await execShellCommand(`explorer.exe ${path}`)

})()

Even cleaner than replacing backslashes, I think this will work for you by resolving the $HOME variable directly into your command line:

await execShellCommand(`explorer.exe "$(wslpath -w $HOME)"`);
Related