Skip to content

Commit

Permalink
Add support for Windows apps referenced by their WSL paths (#118)
Browse files Browse the repository at this point in the history
Fixes #117
  • Loading branch information
stephen-zhao authored and sindresorhus committed Mar 26, 2019
1 parent 54fcb34 commit b30220c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
16 changes: 16 additions & 0 deletions index.js
@@ -1,8 +1,19 @@
'use strict';
const path = require('path');
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 pExecFile('wslpath', ['-w', path]);
return stdout.trim();
};

module.exports = async (target, options) => {
if (typeof target !== 'string') {
throw new TypeError('Expected a `target`');
Expand Down Expand Up @@ -43,6 +54,11 @@ module.exports = async (target, options) => {
}

if (options.app) {
if (isWsl && options.app.startsWith('/mnt/')) {
const winPath = await wslToWindowsPath(options.app);
options.app = winPath;
}

cliArguments.push(options.app);
}

Expand Down
3 changes: 3 additions & 0 deletions readme.md
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
14 changes: 14 additions & 0 deletions test.js
Expand Up @@ -4,13 +4,17 @@ import open from '.';

let chromeName;
let firefoxName;
let chromeWslName;
let firefoxWslName;

if (process.platform === 'darwin') {
chromeName = 'google chrome canary';
firefoxName = 'firefox';
} 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';
Expand Down Expand Up @@ -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']});
});
}

0 comments on commit b30220c

Please sign in to comment.