@@ -2,13 +2,16 @@ import process from 'node:process';
22import { Buffer } from 'node:buffer' ;
33import path from 'node:path' ;
44import { fileURLToPath } from 'node:url' ;
5+ import util from 'node:util' ;
56import childProcess from 'node:child_process' ;
67import fs , { constants as fsConstants } from 'node:fs/promises' ;
78import isWsl from 'is-wsl' ;
89import defineLazyProperty from 'define-lazy-prop' ;
910import defaultBrowser from 'default-browser' ;
1011import isInsideContainer from 'is-inside-container' ;
1112
13+ const execFile = util . promisify ( childProcess . execFile ) ;
14+
1215// Path to included `xdg-open`.
1316const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
1417const localXdgOpenPath = path . join ( __dirname , 'xdg-open' ) ;
@@ -60,6 +63,51 @@ const getWslDrivesMountPoint = (() => {
6063 } ;
6164} ) ( ) ;
6265
66+ /**
67+ Get the PowerShell executable path in WSL environment.
68+
69+ @returns {Promise<string> } The absolute path to the PowerShell executable in WSL.
70+ */
71+ const getPowershellPathFromWsl = async ( ) => {
72+ const mountPoint = await getWslDrivesMountPoint ( ) ;
73+ return `${ mountPoint } c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` ;
74+ } ;
75+
76+ /**
77+ Get the default browser name in Windows from WSL.
78+
79+ @returns {Promise<string> } Browser name.
80+ */
81+ async function getWindowsDefaultBrowserFromWsl ( ) {
82+ const powershellPath = await getPowershellPathFromWsl ( ) ;
83+ const rawCommand = '(Get-ItemProperty -Path "HKCU:\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice").ProgId' ;
84+ const encodedCommand = Buffer . from ( rawCommand , 'utf16le' ) . toString ( 'base64' ) ;
85+
86+ const { stdout} = await execFile (
87+ powershellPath ,
88+ [
89+ '-NoProfile' ,
90+ '-NonInteractive' ,
91+ '-ExecutionPolicy' ,
92+ 'Bypass' ,
93+ '-EncodedCommand' ,
94+ encodedCommand ,
95+ ] ,
96+ { encoding : 'utf8' } ,
97+ ) ;
98+
99+ const progId = stdout . trim ( ) ;
100+
101+ // Map ProgId to browser IDs
102+ const browserMap = {
103+ ChromeHTML : 'com.google.chrome' ,
104+ MSEdgeHTM : 'com.microsoft.edge' ,
105+ FirefoxURL : 'org.mozilla.firefox' ,
106+ } ;
107+
108+ return browserMap [ progId ] ? { id : browserMap [ progId ] } : { } ;
109+ }
110+
63111const pTryEach = async ( array , mapper ) => {
64112 let latestError ;
65113
@@ -123,7 +171,7 @@ const baseOpen = async options => {
123171 edge : '--inPrivate' ,
124172 } ;
125173
126- const browser = await defaultBrowser ( ) ;
174+ const browser = isWsl ? await getWindowsDefaultBrowserFromWsl ( ) : await defaultBrowser ( ) ;
127175 if ( browser . id in ids ) {
128176 const browserName = ids [ browser . id ] ;
129177
@@ -166,10 +214,8 @@ const baseOpen = async options => {
166214 cliArguments . push ( '-a' , app ) ;
167215 }
168216 } else if ( platform === 'win32' || ( isWsl && ! isInsideContainer ( ) && ! app ) ) {
169- const mountPoint = await getWslDrivesMountPoint ( ) ;
170-
171217 command = isWsl
172- ? ` ${ mountPoint } c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`
218+ ? await getPowershellPathFromWsl ( )
173219 : `${ process . env . SYSTEMROOT || process . env . windir || 'C:\\Windows' } \\System32\\WindowsPowerShell\\v1.0\\powershell` ;
174220
175221 cliArguments . push (
0 commit comments