@@ -2,6 +2,10 @@ var common = require('./common');
22var fs = require ( 'fs' ) ;
33var path = require ( 'path' ) ;
44
5+ // XP's system default value for PATHEXT system variable, just in case it's not
6+ // set on Windows.
7+ var XP_DEFAULT_PATHEXT = '.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh' ;
8+
59// Cross-platform method for splitting environment PATH variables
610function splitPath ( p ) {
711 if ( ! p )
@@ -26,7 +30,8 @@ function checkPath(path) {
2630//@ var nodeExec = which('node');
2731//@ ```
2832//@
29- //@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
33+ //@ Searches for `command` in the system's PATH. On Windows, this uses the
34+ //@ `PATHEXT` variable to append the extension if it's not already executable.
3035//@ Returns string containing the absolute path to the command.
3136function _which ( options , cmd ) {
3237 if ( ! cmd )
@@ -43,26 +48,37 @@ function _which(options, cmd) {
4348 if ( where )
4449 return ; // already found it
4550
46- var attempt = path . resolve ( dir + '/' + cmd ) ;
51+ var attempt = path . resolve ( dir , cmd ) ;
4752
4853 if ( common . platform === 'win' ) {
49- var baseAttempt = attempt ;
50- attempt = baseAttempt + '.exe' ;
51- if ( checkPath ( attempt ) ) {
52- where = attempt ;
53- return ;
54- }
55- attempt = baseAttempt + '.bat' ;
56- if ( checkPath ( attempt ) ) {
57- where = attempt ;
58- return ;
54+ attempt = attempt . toUpperCase ( ) ;
55+
56+ // In case the PATHEXT variable is somehow not set (e.g.
57+ // child_process.spawn with an empty environment), use the XP default.
58+ var pathExtEnv = process . env . PATHEXT || XP_DEFAULT_PATHEXT ;
59+ var pathExtArray = splitPath ( pathExtEnv . toUpperCase ( ) ) ;
60+ var i ;
61+
62+ // If the extension is already in PATHEXT, just return that.
63+ for ( i = 0 ; i < pathExtArray . length ; i ++ ) {
64+ var ext = pathExtArray [ i ] ;
65+ if ( attempt . slice ( - ext . length ) === ext && checkPath ( attempt ) ) {
66+ where = attempt ;
67+ return ;
68+ }
5969 }
60- attempt = baseAttempt + '.cmd' ;
61- if ( checkPath ( attempt ) ) {
62- where = attempt ;
63- return ;
70+
71+ // Cycle through the PATHEXT variable
72+ var baseAttempt = attempt ;
73+ for ( i = 0 ; i < pathExtArray . length ; i ++ ) {
74+ attempt = baseAttempt + pathExtArray [ i ] ;
75+ if ( checkPath ( attempt ) ) {
76+ where = attempt ;
77+ return ;
78+ }
6479 }
6580 } else {
81+ // Assume it's Unix-like
6682 if ( checkPath ( attempt ) ) {
6783 where = attempt ;
6884 return ;
0 commit comments