From bd06170c03179d7948a216e1162c5c4137a9ec20 Mon Sep 17 00:00:00 2001 From: Stephen Zhao Date: Mon, 18 Mar 2019 20:46:28 +0100 Subject: [PATCH 1/4] Add support for windows apps referenced by their WSL paths --- index.js | 12 ++++++++++++ test.js | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/index.js b/index.js index 704ebc8..d6011fc 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,17 @@ 'use strict'; const path = require('path'); const childProcess = require('child_process'); +const util = require('util'); const isWsl = require('is-wsl'); +// Converts a path from WSL format to Windows format +// e.g. /mnt/c/Program Files/Example/MyApp.exe +// => C:\Program Files\Example\MyApp.exe +const wslToWindowsPath = async path => { + const { stdout, stderr } = await util.promisify(childProcess.execFile)('wslpath', ['-w', path]); + return stdout.toString().trim(); +} + module.exports = async (target, options) => { if (typeof target !== 'string') { throw new TypeError('Expected a `target`'); @@ -43,6 +52,9 @@ module.exports = async (target, options) => { } if (options.app) { + if (isWsl && options.app.startsWith('/mnt/')) { + options.app = await wslToWindowsPath(options.app); + } cliArguments.push(options.app); } diff --git a/test.js b/test.js index 477e0c9..3d562d4 100644 --- a/test.js +++ b/test.js @@ -4,6 +4,8 @@ import open from '.'; let chromeName; let firefoxName; +let chromeWslName; +let firefoxWslName; if (process.platform === 'darwin') { chromeName = 'google chrome canary'; @@ -11,6 +13,8 @@ if (process.platform === 'darwin') { } else if (process.platform === 'win32' || isWsl) { chromeName = 'Chrome'; firefoxName = 'C:\\Program Files\\Mozilla Firefox\\firefox.exe'; + chromeWslName = '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'; + firefoxWslName = '/mnt/c/Program Files/Mozilla Firefox/firefox.exe'; } else if (process.platform === 'linux') { chromeName = 'google-chrome'; firefoxName = 'firefox'; @@ -45,3 +49,13 @@ test('return the child process when called', async t => { const cp = await open('index.js'); t.true('stdout' in cp); }); + +if (isWsl) { + test('open url in specified windows app given a wsl path to the app', async () => { + await open('http://sindresorhus.com', {app: firefoxWslName}); + }); + + test('open url in specified windows app with arguments given a wsl path to the app', async () => { + await open('http://sindresorhus.com', {app: [chromeWslName, '--incognito']}); + }); +} From 0390043070a6b3235556ced5b19ca3b241b4e5da Mon Sep 17 00:00:00 2001 From: Stephen Zhao Date: Mon, 18 Mar 2019 21:15:53 +0100 Subject: [PATCH 2/4] Fix xo lint errors --- index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index d6011fc..58ec64d 100644 --- a/index.js +++ b/index.js @@ -8,9 +8,9 @@ const isWsl = require('is-wsl'); // e.g. /mnt/c/Program Files/Example/MyApp.exe // => C:\Program Files\Example\MyApp.exe const wslToWindowsPath = async path => { - const { stdout, stderr } = await util.promisify(childProcess.execFile)('wslpath', ['-w', path]); + const {stdout} = await util.promisify(childProcess.execFile)('wslpath', ['-w', path]); return stdout.toString().trim(); -} +}; module.exports = async (target, options) => { if (typeof target !== 'string') { @@ -53,8 +53,10 @@ module.exports = async (target, options) => { if (options.app) { if (isWsl && options.app.startsWith('/mnt/')) { - options.app = await wslToWindowsPath(options.app); + const winPath = await wslToWindowsPath(options.app); + options.app = winPath; } + cliArguments.push(options.app); } From 0fd474d7dfbcbe546087058760e6796af9d4e3c1 Mon Sep 17 00:00:00 2001 From: Stephen Zhao Date: Tue, 19 Mar 2019 14:25:28 +0100 Subject: [PATCH 3/4] Factor out promisify call & del redundant toString call --- index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 58ec64d..71afe9a 100644 --- a/index.js +++ b/index.js @@ -4,12 +4,14 @@ const childProcess = require('child_process'); const util = require('util'); const isWsl = require('is-wsl'); +const pExecFile = util.promisify(childProcess.execFile); + // Converts a path from WSL format to Windows format // e.g. /mnt/c/Program Files/Example/MyApp.exe // => C:\Program Files\Example\MyApp.exe const wslToWindowsPath = async path => { - const {stdout} = await util.promisify(childProcess.execFile)('wslpath', ['-w', path]); - return stdout.toString().trim(); + const {stdout} = await pExecFile('wslpath', ['-w', path]); + return stdout.trim(); }; module.exports = async (target, options) => { From eeec5a27236d2591b3f482cc8cb185c4e324cfbe Mon Sep 17 00:00:00 2001 From: Stephen Zhao Date: Tue, 19 Mar 2019 14:48:51 +0100 Subject: [PATCH 4/4] Add mention of WSL support to readme --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index c534275..a852ca5 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,7 @@ If need this for Electron, use [`shell.openItem()`](https://electronjs.org/docs/ - Safer as it uses `spawn` instead of `exec`. - Fixes most of the open `node-open` issues. - Includes the latest [`xdg-open` script](http://cgit.freedesktop.org/xdg/xdg-utils/commit/?id=c55122295c2a480fa721a9614f0e2d42b2949c18) for Linux. +- Supports WSL paths to Windows apps under `/mnt/*`. ## Install @@ -81,6 +82,8 @@ Specify the app to open the `target` with, or an array with the app and app argu The app name is platform dependent. Don't hard code it in reusable modules. For example, Chrome is `google chrome` on macOS, `google-chrome` on Linux and `chrome` on Windows. +You may also pass in the app's full path. For example on WSL, this can be `/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe` for the Windows installation of Chrome. + ## Related