import { spawn as spawnInternal } from 'child_process'; import * as Path from 'path'; /** Get the path segments in the user's `Path`. */ export async function getPathSegments(): Promise> { let powershellPath: string; const systemRoot = process.env.SystemRoot; if (systemRoot != null) { const system32Path = Path.join(systemRoot, 'System32'); powershellPath = Path.join( system32Path, 'WindowsPowerShell', 'v1.0', 'powershell.exe' ); } else { powershellPath = 'powershell.exe'; } const args = [ '-noprofile', '-ExecutionPolicy', 'RemoteSigned', '-command', // Set encoding and execute the command, capture the output, and return it // via .NET's console in order to have consistent UTF-8 encoding. // See http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell // to address https://github.com/atom/atom/issues/5063 ` [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 $output=[environment]::GetEnvironmentVariable('Path', 'User') [Console]::WriteLine($output) `, ]; const stdout = await spawn(powershellPath, args); const pathOutput = stdout.replace(/^\s+|\s+$/g, ''); return pathOutput.split(/;+/).filter(segment => segment.length); } /** Set the user's `Path`. */ export async function setPathSegments( paths: ReadonlyArray ): Promise { let setxPath: string; const systemRoot = process.env['SystemRoot']; if (systemRoot) { const system32Path = Path.join(systemRoot, 'System32'); setxPath = Path.join(system32Path, 'setx.exe'); } else { setxPath = 'setx.exe'; } await spawn(setxPath, ['Path', paths.join(';')]); } /** Spawn a command with arguments and capture its output. */ export function spawn( command: string, args: ReadonlyArray ): Promise { try { const child = spawnInternal(command, args as string[]); return new Promise((resolve, reject) => { let stdout = ''; child.stdout.on('data', data => { stdout += data; }); child.on('close', code => { if (code === 0) { resolve(stdout); } else { reject(new Error(`Command "${command} ${args}" failed: "${stdout}"`)); } }); child.on('error', (err: Error) => { reject(err); }); // This is necessary if using Powershell 2 on Windows 7 to get the events // to raise. // See http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs child.stdin.end(); }); } catch (error) { return Promise.reject(error); } }