91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
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<ReadonlyArray<string>> {
|
|
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<string>
|
|
): Promise<void> {
|
|
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<string>
|
|
): Promise<string> {
|
|
try {
|
|
const child = spawnInternal(command, args as string[]);
|
|
return new Promise<string>((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);
|
|
}
|
|
}
|