5
5
6
6
import { spawn } from 'child_process' ;
7
7
import { homedir } from 'os' ;
8
- import { basename , dirname , extname , isAbsolute , join } from '../../../base/common/path.js' ;
9
- import { localize } from '../../../nls.js' ;
8
+ import { first , Promises } from '../../../base/common/async.js' ;
10
9
import { CancellationToken , CancellationTokenSource } from '../../../base/common/cancellation.js' ;
11
10
import { toErrorMessage } from '../../../base/common/errorMessage.js' ;
12
11
import { CancellationError , isCancellationError } from '../../../base/common/errors.js' ;
12
+ import { clamp } from '../../../base/common/numbers.js' ;
13
+ import { basename , join } from '../../../base/common/path.js' ;
13
14
import { IProcessEnvironment , isMacintosh , isWindows , OS } from '../../../base/common/platform.js' ;
14
15
import { generateUuid } from '../../../base/common/uuid.js' ;
16
+ import { StreamSplitter } from '../../../base/node/nodeStreams.js' ;
17
+ import { Promises as FSPromises } from '../../../base/node/pfs.js' ;
15
18
import { getSystemShell } from '../../../base/node/shell.js' ;
19
+ import { localize } from '../../../nls.js' ;
20
+ import { IConfigurationService } from '../../configuration/common/configuration.js' ;
16
21
import { NativeParsedArgs } from '../../environment/common/argv.js' ;
17
22
import { isLaunchedFromCli } from '../../environment/node/argvHelper.js' ;
18
23
import { ILogService } from '../../log/common/log.js' ;
19
- import { first , Promises } from '../../../base/common/async.js' ;
20
- import { IConfigurationService } from '../../configuration/common/configuration.js' ;
21
- import { clamp } from '../../../base/common/numbers.js' ;
22
- import { findExecutable , getWindowPathExtensions } from '../../../base/node/processes.js' ;
23
- import { equalsIgnoreCase } from '../../../base/common/strings.js' ;
24
- import { Promises as FSPromises } from '../../../base/node/pfs.js' ;
25
- import { StreamSplitter } from '../../../base/node/nodeStreams.js' ;
26
24
27
25
let shellEnvPromise : Promise < typeof process . env > | undefined = undefined ;
28
26
@@ -36,6 +34,13 @@ let shellEnvPromise: Promise<typeof process.env> | undefined = undefined;
36
34
*/
37
35
export async function getResolvedShellEnv ( configurationService : IConfigurationService , logService : ILogService , args : NativeParsedArgs , env : IProcessEnvironment ) : Promise < typeof process . env > {
38
36
37
+ // Skip on windows
38
+ if ( isWindows ) {
39
+ logService . trace ( 'resolveShellEnv(): skipped (Windows)' ) ;
40
+
41
+ return { } ;
42
+ }
43
+
39
44
// Skip if --force-disable-user-env
40
45
if ( args [ 'force-disable-user-env' ] ) {
41
46
logService . trace ( 'resolveShellEnv(): skipped (--force-disable-user-env)' ) ;
@@ -113,21 +118,13 @@ async function doResolveShellEnv(logService: ILogService, token: CancellationTok
113
118
} ;
114
119
115
120
logService . trace ( 'doResolveShellEnv#env' , env ) ;
116
- const systemShell = await getSystemShell ( OS , env ) ; // note: windows always resolves a powershell instance
121
+ const systemShell = await getSystemShell ( OS , env ) ;
117
122
logService . trace ( 'doResolveShellEnv#shell' , systemShell ) ;
118
123
119
- let name = basename ( systemShell ) ;
120
- if ( isWindows ) {
121
- const nameExt = extname ( name ) ;
122
- if ( getWindowPathExtensions ( ) . some ( e => equalsIgnoreCase ( e , nameExt ) ) ) {
123
- name = name . substring ( 0 , name . length - nameExt . length ) ; // remove any .exe/.cmd/... from the name for matching logic on Windows
124
- }
125
- }
126
-
124
+ const name = basename ( systemShell ) ;
127
125
let command : string , shellArgs : Array < string > ;
128
- const extraArgs = '' ;
129
126
if ( / ^ (?: p w s h | p o w e r s h e l l ) (?: - p r e v i e w ) ? $ / . test ( name ) ) {
130
- const profilePaths = await getPowershellProfilePaths ( systemShell ) ;
127
+ const profilePaths = getPowershellProfilePaths ( ) ;
131
128
const profilePathThatExists = await first ( profilePaths . map ( profilePath => async ( ) => ( await FSPromises . exists ( profilePath ) ) ? profilePath : undefined ) ) ;
132
129
if ( ! profilePathThatExists ) {
133
130
logService . trace ( 'doResolveShellEnv#noPowershellProfile after testing paths' , profilePaths ) ;
@@ -141,25 +138,15 @@ async function doResolveShellEnv(logService: ILogService, token: CancellationTok
141
138
// so we use "double single quotes" which is how you escape single
142
139
// quotes inside of a single quoted string.
143
140
command = `Write-Output '${ mark } '; [System.Environment]::GetEnvironmentVariables() | ConvertTo-Json -Compress; Write-Output '${ mark } '` ;
144
-
145
- // Improve unicode support on Windows by setting the code page to UTF-8
146
- if ( isWindows ) {
147
- command = `chcp 65001; ${ command } ` ;
148
- }
149
-
150
- // -Login is not a supported argument on PowerShell 5, which is a version of
151
- // powershell that is exclusive to Windows. Providing it would error. Also,
152
- // -Login is documented as a no-op on Windows on Powershell 7, so simply omit
153
- // it to avoid causing errors or requiring a version check.
154
- shellArgs = isWindows ? [ '-Command' ] : [ '-Login' , '-Command' ] ;
141
+ shellArgs = [ '-Login' , '-Command' ] ;
155
142
} else if ( name === 'nu' ) { // nushell requires ^ before quoted path to treat it as a command
156
- command = `^'${ process . execPath } ' ${ extraArgs } -p '"${ mark } " + JSON.stringify(process.env) + "${ mark } "'` ;
143
+ command = `^'${ process . execPath } ' -p '"${ mark } " + JSON.stringify(process.env) + "${ mark } "'` ;
157
144
shellArgs = [ '-i' , '-l' , '-c' ] ;
158
145
} else if ( name === 'xonsh' ) { // #200374: native implementation is shorter
159
146
command = `import os, json; print("${ mark } ", json.dumps(dict(os.environ)), "${ mark } ")` ;
160
147
shellArgs = [ '-i' , '-l' , '-c' ] ;
161
148
} else {
162
- command = `'${ process . execPath } ' ${ extraArgs } -p '"${ mark } " + JSON.stringify(process.env) + "${ mark } "'` ;
149
+ command = `'${ process . execPath } ' -p '"${ mark } " + JSON.stringify(process.env) + "${ mark } "'` ;
163
150
164
151
if ( name === 'tcsh' || name === 'csh' ) {
165
152
shellArgs = [ '-ic' ] ;
@@ -296,37 +283,11 @@ async function doResolveShellEnv(logService: ILogService, token: CancellationTok
296
283
*
297
284
* @see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.5
298
285
*/
299
- async function getPowershellProfilePaths ( psExecutable : string ) {
286
+ function getPowershellProfilePaths ( ) {
300
287
const paths : string [ ] = [ ] ;
301
288
const userHome = homedir ( ) ;
302
- if ( isWindows ) {
303
289
304
- // "The $PSHOME variable stores the installation directory for PowerShell" --
305
- // but this is not set ambiently on the operating system.
306
- let pshome = process . env . PSHOME ;
307
- if ( ! pshome ) {
308
- if ( ! isAbsolute ( psExecutable ) ) {
309
- const found = await findExecutable ( psExecutable ) ;
310
- if ( ! found ) {
311
- return [ ] ;
312
- }
313
-
314
- pshome = dirname ( found ) ;
315
- } else {
316
- pshome = dirname ( psExecutable ) ;
317
- }
318
- }
319
-
320
- paths . push (
321
- join ( pshome , 'Profile.ps1' ) , // All Users, All Hosts
322
- join ( pshome , 'Microsoft.PowerShell_profile.ps1' ) , // All Users, Current Host
323
- join ( userHome , 'Documents' , 'PowerShell' , 'Profile.ps1' ) , // Current User, All Hosts
324
- join ( userHome , 'Documents' , 'PowerShell' , 'Microsoft.PowerShell_profile.ps1' ) , // Current User, Current Host
325
-
326
- join ( userHome , 'Documents' , 'WindowsPowerShell' , 'Profile.ps1' ) , // (Powershell 5) Current User, All Hosts
327
- join ( userHome , 'Documents' , 'WindowsPowerShell' , 'Microsoft.PowerShell_profile.ps1' ) , // (Powershell 5) Current User, Current Host
328
- ) ;
329
- } else if ( isMacintosh ) {
290
+ if ( isMacintosh ) {
330
291
331
292
// note: powershell 7 is the first (and yet only) powershell version on posix,
332
293
// so no need to look for any extra paths yet.
0 commit comments