Rewrite code that call external programs.
This commit is contained in:
parent
e49c13d677
commit
67d20da312
3 changed files with 190 additions and 145 deletions
133
lib/read.cs.js
133
lib/read.cs.js
|
@ -2,43 +2,67 @@
|
||||||
|
|
||||||
var
|
var
|
||||||
FSO_ForReading = 1, FSO_ForWriting = 2,
|
FSO_ForReading = 1, FSO_ForWriting = 2,
|
||||||
|
PS_MSG = 'Microsoft Windows PowerShell is required.\n' +
|
||||||
|
'https://technet.microsoft.com/en-us/library/hh847837.aspx',
|
||||||
|
|
||||||
fso, tty,
|
input, fso, tty,
|
||||||
args =// Array.prototype.slice.call(WScript.Arguments),
|
options = (function(conf) {
|
||||||
(function() {
|
var options = {}, arg, args =// Array.prototype.slice.call(WScript.Arguments),
|
||||||
var args = [], i, iLen;
|
(function() {
|
||||||
for (i = 0, iLen = WScript.Arguments.length; i < iLen; i++)
|
var args = [], i, iLen;
|
||||||
{ args.push(WScript.Arguments(i)); }
|
for (i = 0, iLen = WScript.Arguments.length; i < iLen; i++)
|
||||||
return args;
|
{ args.push(WScript.Arguments(i)); }
|
||||||
})(),
|
return args;
|
||||||
arg, options = {};
|
})(),
|
||||||
|
confLc = {}, key;
|
||||||
|
|
||||||
while (typeof(arg = args.shift()) === 'string') {
|
function decodeDOS(arg) {
|
||||||
arg = arg.toLowerCase();
|
return arg.replace(/#(\d+);/g, function(str, charCode) {
|
||||||
if (arg === '--display') {
|
return String.fromCharCode(+charCode);
|
||||||
options.display = args.shift();
|
});
|
||||||
} else if (arg === '--noechoback') {
|
}
|
||||||
options.noEchoBack = true;
|
|
||||||
} else if (arg === '--mask') {
|
for (key in conf) {
|
||||||
options.mask = args.shift();
|
if (conf.hasOwnProperty(key))
|
||||||
} else if (arg === '--keyin') {
|
{ confLc[key.toLowerCase()] = {key: key, type: conf[key]}; }
|
||||||
options.keyIn = true;
|
}
|
||||||
} else if (arg === '--encoded') {
|
|
||||||
options.encoded = true;
|
while (typeof(arg = args.shift()) === 'string') {
|
||||||
}
|
if (!(arg = (arg.match(/^\-+(.+)$/) || [])[1])) { continue; }
|
||||||
|
arg = arg.toLowerCase();
|
||||||
|
if (confLc[arg]) {
|
||||||
|
options[confLc[arg].key] =
|
||||||
|
confLc[arg].type === 'boolean' ? true :
|
||||||
|
confLc[arg].type === 'string' ? args.shift() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (key in conf) {
|
||||||
|
if (conf.hasOwnProperty(key) && conf[key] === 'string') {
|
||||||
|
if (typeof options[key] !== 'string') { options[key] = ''; }
|
||||||
|
else if (options.encoded) { options[key] = decodeDOS(options[key]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
})({
|
||||||
|
display: 'string',
|
||||||
|
noEchoBack: 'boolean',
|
||||||
|
mask: 'string',
|
||||||
|
keyIn: 'boolean',
|
||||||
|
encoded: 'boolean'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!options.noEchoBack && !options.keyIn) {
|
||||||
|
if (options.display !== '') { writeTTY(options.display); }
|
||||||
|
input = readByCS();
|
||||||
|
} else if (options.noEchoBack && !options.keyIn && options.mask === '*') {
|
||||||
|
if (options.display !== '') { writeTTY(options.display); }
|
||||||
|
input = readByPW();
|
||||||
|
} else {
|
||||||
|
WScript.StdErr.WriteLine(PS_MSG);
|
||||||
|
WScript.Quit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.encoded) {
|
WScript.StdOut.Write('\'' + input + '\'');
|
||||||
if (typeof options.display === 'string')
|
|
||||||
{ options.display = decodeDOS(options.display); }
|
|
||||||
if (typeof options.mask === 'string')
|
|
||||||
{ options.mask = decodeDOS(options.mask); }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof options.display === 'string' && options.display !== '')
|
|
||||||
{ writeTTY(options.display); }
|
|
||||||
|
|
||||||
WScript.StdOut.Write("'" + readTTY() + "'");
|
|
||||||
|
|
||||||
WScript.Quit();
|
WScript.Quit();
|
||||||
|
|
||||||
|
@ -48,50 +72,28 @@ function writeTTY(text) {
|
||||||
tty.Write(text);
|
tty.Write(text);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
WScript.StdErr.WriteLine('TTY Write Error: ' + e.number +
|
WScript.StdErr.WriteLine('TTY Write Error: ' + e.number +
|
||||||
'\n' + e.description);
|
'\n' + e.description + '\n' + PS_MSG);
|
||||||
WScript.Quit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function readTTY() {
|
|
||||||
|
|
||||||
// function psExists() {
|
|
||||||
// var envPs = getShell().Environment('System')('PSModulePath');
|
|
||||||
// return typeof envPs === 'string' && envPs !== '';
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!options.noEchoBack && !options.keyIn) {
|
|
||||||
return readByCS();
|
|
||||||
// } else if (psExists()) {
|
|
||||||
// return readByPS();
|
|
||||||
} else if (options.noEchoBack && !options.keyIn && options.mask === '*') {
|
|
||||||
return readByPW();
|
|
||||||
} else {
|
|
||||||
WScript.StdErr.WriteLine('Microsoft Windows PowerShell is required.\n' +
|
|
||||||
'https://technet.microsoft.com/ja-jp/library/hh847837.aspx');
|
|
||||||
WScript.Quit(1);
|
WScript.Quit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readByCS() {
|
function readByCS() {
|
||||||
WScript.StdErr.Write('<<readByCS>>'); //_DBG_
|
|
||||||
var text;
|
var text;
|
||||||
try {
|
try {
|
||||||
text = getFso().OpenTextFile('CONIN$', FSO_ForReading).ReadLine();
|
text = getFso().OpenTextFile('CONIN$', FSO_ForReading).ReadLine();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
WScript.StdErr.WriteLine('TTY Read Error: ' + e.number +
|
WScript.StdErr.WriteLine('TTY Read Error: ' + e.number +
|
||||||
'\n' + e.description);
|
'\n' + e.description + '\n' + PS_MSG);
|
||||||
WScript.Quit(1);
|
WScript.Quit(1);
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TTY must be STDIN that is not redirected and not piped.
|
||||||
function readByPW() {
|
function readByPW() {
|
||||||
WScript.StdErr.Write('<<readByPW>>'); //_DBG_
|
var text;
|
||||||
var pw;
|
|
||||||
// exit-code is not returned even if an error is thrown.
|
|
||||||
try {
|
try {
|
||||||
pw = WScript.CreateObject('ScriptPW.Password').GetPassword()
|
text = WScript.CreateObject('ScriptPW.Password').GetPassword()
|
||||||
// Bug? Illegal data may be returned when user types before initializing.
|
// Bug? Illegal data may be returned when user types before initializing.
|
||||||
.replace(/[\u4000-\u40FF]/g, function(chr) {
|
.replace(/[\u4000-\u40FF]/g, function(chr) {
|
||||||
var charCode = chr.charCodeAt(0);
|
var charCode = chr.charCodeAt(0);
|
||||||
|
@ -100,21 +102,14 @@ function readByPW() {
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
WScript.StdErr.WriteLine('ScriptPW.Password Error: ' + e.number +
|
WScript.StdErr.WriteLine('ScriptPW.Password Error: ' + e.number +
|
||||||
'\n' + e.description);
|
'\n' + e.description + '\n' + PS_MSG);
|
||||||
WScript.Quit(1);
|
WScript.Quit(1);
|
||||||
}
|
}
|
||||||
writeTTY('\n');
|
writeTTY('\n');
|
||||||
return pw;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFso() {
|
function getFso() {
|
||||||
if (!fso) { fso = new ActiveXObject('Scripting.FileSystemObject'); }
|
if (!fso) { fso = new ActiveXObject('Scripting.FileSystemObject'); }
|
||||||
return fso;
|
return fso;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeDOS(arg) {
|
|
||||||
return arg.replace(/#(\d+);/g, function(str, charCode) {
|
|
||||||
return String.fromCharCode(+charCode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
69
lib/read.ps1
69
lib/read.ps1
|
@ -2,7 +2,7 @@
|
||||||
Param(
|
Param(
|
||||||
[string] $display,
|
[string] $display,
|
||||||
[switch] $noEchoBack,
|
[switch] $noEchoBack,
|
||||||
[string] $mask = '*',
|
[string] $mask,
|
||||||
[switch] $keyIn,
|
[switch] $keyIn,
|
||||||
[switch] $encoded
|
[switch] $encoded
|
||||||
)
|
)
|
||||||
|
@ -14,24 +14,35 @@ trap {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeDOS($arg) {
|
function decodeDOS ($arg) {
|
||||||
[Regex]::Replace($arg, '#(\d+);', { [char][int] $args[0].Groups[1].Value })
|
[Regex]::Replace($arg, '#(\d+);', { [char][int] $args[0].Groups[1].Value })
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($encoded) {
|
$options = @{}
|
||||||
if ($display -ne '') { $display = decodeDOS $display }
|
foreach ($arg in @('display', 'noEchoBack', 'mask', 'keyIn', 'encoded')) {
|
||||||
if ($mask -ne '') { $mask = decodeDOS $mask }
|
$options.Add($arg, (Get-Variable $arg -ValueOnly))
|
||||||
|
}
|
||||||
|
if ($options.encoded) {
|
||||||
|
$argList = New-Object string[] $options.Keys.Count
|
||||||
|
$options.Keys.CopyTo($argList, 0);
|
||||||
|
foreach ($arg in $argList) {
|
||||||
|
if (($options[$arg] -is [string]) -and ($options[$arg] -ne ''))
|
||||||
|
{ $options[$arg] = decodeDOS $options[$arg] }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Warning "[PS] display: <$display>" #_DBG
|
[string] $inputTTY = ''
|
||||||
Write-Warning "[PS] noEchoBack: $noEchoBack" #_DBG
|
[bool] $isInputLine = $False
|
||||||
Write-Warning "[PS] mask: <$mask>" #_DBG
|
[bool] $isEditable = (-not $options.noEchoBack) -and (-not $options.keyIn)
|
||||||
Write-Warning "[PS] keyIn: $keyIn" #_DBG
|
|
||||||
|
function writeTTY ($text) {
|
||||||
|
execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline')
|
||||||
|
$script:isInputLine = $True
|
||||||
|
}
|
||||||
|
|
||||||
# Instant method that opens TTY without CreateFile via P/Invoke in .NET Framework
|
# Instant method that opens TTY without CreateFile via P/Invoke in .NET Framework
|
||||||
# **NOTE** Don't include special characters in $command when $getRes is True.
|
# **NOTE** Don't include special characters of DOS in $command when $getRes is True.
|
||||||
function execWithTTY ($command, $getRes = $False) {
|
function execWithTTY ($command, $getRes = $False) {
|
||||||
Write-Warning "[PS] command: <$command> getRes: $getRes" #_DBG
|
|
||||||
if ($getRes) {
|
if ($getRes) {
|
||||||
$res = (cmd.exe /C "<CON powershell.exe -Command $command")
|
$res = (cmd.exe /C "<CON powershell.exe -Command $command")
|
||||||
if ($LastExitCode -ne 0) { exit 1 }
|
if ($LastExitCode -ne 0) { exit 1 }
|
||||||
|
@ -43,21 +54,19 @@ function execWithTTY ($command, $getRes = $False) {
|
||||||
return $res
|
return $res
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeTTY ($text) {
|
if ($options.display -ne '') {
|
||||||
execWithTTY ('Write-Host ''' + ($text -replace '''', '''''') + ''' -NoNewline')
|
writeTTY $options.display
|
||||||
|
$options.display = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
[string] $inputTTY = ''
|
if ($options.noEchoBack -and (-not $options.keyIn) -and ($options.mask -eq '*')) {
|
||||||
|
|
||||||
if ($noEchoBack -and (-not $keyIn) -and ($mask -eq '*')) {
|
|
||||||
$inputTTY = execWithTTY ('$inputTTY = Read-Host -AsSecureString;' +
|
$inputTTY = execWithTTY ('$inputTTY = Read-Host -AsSecureString;' +
|
||||||
'$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputTTY);' +
|
'$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inputTTY);' +
|
||||||
'[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)') $True
|
'[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)') $True
|
||||||
return $inputTTY
|
return '''' + $inputTTY + ''''
|
||||||
}
|
}
|
||||||
|
|
||||||
$isEditable = (-not $noEchoBack) -and (-not $keyIn)
|
if ($options.keyIn) { $reqSize = 1 }
|
||||||
if ($keyIn) { $reqSize = 1 }
|
|
||||||
else { $reqSize = 1024 } # dummy
|
else { $reqSize = 1024 } # dummy
|
||||||
|
|
||||||
while ($True) {
|
while ($True) {
|
||||||
|
@ -69,25 +78,27 @@ while ($True) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($chunk -eq '') { break }
|
if ($chunk -eq '') { break }
|
||||||
|
# other ctrl-chars
|
||||||
$chunk = $chunk -replace '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', ''
|
$chunk = $chunk -replace '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', ''
|
||||||
if ($chunk -eq '') { continue }
|
if ($chunk -eq '') { continue }
|
||||||
|
|
||||||
if (-not $isEditable) {
|
if (-not $isEditable) {
|
||||||
$displayInput = $chunk -replace '[\r\n]', ''
|
$displayTmp = $chunk -replace '[\r\n]', ''
|
||||||
if ($displayInput -ne '') {
|
if ($displayTmp -ne '') {
|
||||||
if ($noEchoBack) {
|
if ($options.noEchoBack) {
|
||||||
if ($mask -eq '') { $displayInput = '' }
|
if ($options.mask -eq '') { $displayTmp = '' }
|
||||||
else { $displayInput = $displayInput -replace '.', $mask }
|
else { $displayTmp = $options.mask * $displayTmp.Length }
|
||||||
}
|
}
|
||||||
if ($displayInput -ne '') { writeTTY $displayInput }
|
if ($displayTmp -ne '') { writeTTY $displayTmp }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$inputTTY += $chunk
|
$inputTTY += $chunk
|
||||||
if (($inputTTY -match '[\r\n]$') -or ($keyIn -and ($inputTTY.Length -ge $reqSize)))
|
if (($inputTTY -match '[\r\n]$') -or
|
||||||
{ break }
|
($options.keyIn -and ($inputTTY.Length -ge $reqSize))) { break }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not $isEditable) { writeTTY "`n" } # new-line
|
if ((-not $isEditable) -and (-not ($options.keyIn -and (-not $isInputLine))))
|
||||||
|
{ execWithTTY 'Write-Host ''''' } # new line
|
||||||
|
|
||||||
return '''' + $inputTTY + '''' #DBG
|
return '''' + $inputTTY + ''''
|
||||||
|
|
|
@ -27,9 +27,16 @@ var
|
||||||
useExt = false,
|
useExt = false,
|
||||||
|
|
||||||
fdR = 'none', fdW, ttyR, isRawMode = false,
|
fdR = 'none', fdW, ttyR, isRawMode = false,
|
||||||
extHostPath, extScriptPath, tempdir, salt = 0;
|
extHostPath, extHostArgs, tempdir, salt = 0;
|
||||||
|
|
||||||
function readlineSync(options) { // display, mask are string
|
/*
|
||||||
|
display: string
|
||||||
|
noEchoBack: boolean
|
||||||
|
mask: string
|
||||||
|
keyIn: boolean
|
||||||
|
noTrim: boolean
|
||||||
|
*/
|
||||||
|
function readlineSync(options) {
|
||||||
var input = '', displayTmp;
|
var input = '', displayTmp;
|
||||||
|
|
||||||
function tryExt() {
|
function tryExt() {
|
||||||
|
@ -187,48 +194,45 @@ function readlineSync(options) { // display, mask are string
|
||||||
}
|
}
|
||||||
|
|
||||||
function readlineExt(options) {
|
function readlineExt(options) {
|
||||||
var cmdArgs = [], execArgs, res = {},
|
var hostArgs, res = {},
|
||||||
execOptions = {
|
execOptions = {env: process.env, encoding: encoding};
|
||||||
env: process.env,
|
|
||||||
// ScriptPW (Win XP and Server2003) needs TTY stream as STDIN.
|
|
||||||
// In this case, If STDIN isn't TTY, an error is thrown.
|
|
||||||
stdio: [process.stdin],
|
|
||||||
encoding: encoding
|
|
||||||
};
|
|
||||||
|
|
||||||
extHostPath = extHostPath || (IS_WIN ? 'cscript.exe' : '/bin/sh');
|
if (!extHostPath) {
|
||||||
extScriptPath = extScriptPath || (__dirname + (IS_WIN ? '\\read.cs.js' : '/read.sh'));
|
if (IS_WIN) {
|
||||||
|
if (process.env.PSModulePath) { // Windows PowerShell
|
||||||
// To send any text to crazy Windows shell safely.
|
extHostPath = 'powershell.exe';
|
||||||
function encodeDOS(arg) {
|
extHostArgs = ['-ExecutionPolicy', 'Bypass', '-File', __dirname + '\\read.ps1'];
|
||||||
return arg.replace(/[^\w\u0080-\uFFFF]/g, function(chr) {
|
} else { // Windows Script Host
|
||||||
return '#' + chr.charCodeAt(0) + ';';
|
extHostPath = 'cscript.exe';
|
||||||
});
|
extHostArgs = ['//nologo', __dirname + '\\read.cs.js'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
extHostPath = '/bin/sh';
|
||||||
|
extHostArgs = [__dirname + '/read.sh'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (IS_WIN && !process.env.PSModulePath) { // Windows Script Host
|
||||||
if (options.noEchoBack) { cmdArgs.push('--noechoback'); }
|
// ScriptPW (Win XP and Server2003) needs TTY stream as STDIN.
|
||||||
if (options.keyIn) { cmdArgs.push('--keyin'); }
|
// In this case, If STDIN isn't TTY, an error is thrown.
|
||||||
if (options.display !== '') {
|
execOptions.stdio = [process.stdin];
|
||||||
cmdArgs = cmdArgs.concat('--display', IS_WIN ?
|
|
||||||
[encodeDOS(options.display), '--encoded'] : options.display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childProc.execFileSync) {
|
if (childProc.execFileSync) {
|
||||||
execArgs = (IS_WIN ? ['//nologo', extScriptPath] : [extScriptPath]).concat(cmdArgs);
|
hostArgs = getHostArgs(options);
|
||||||
try {
|
try {
|
||||||
res.input = childProc.execFileSync(extHostPath, execArgs, execOptions);
|
res.input = childProc.execFileSync(extHostPath, hostArgs, execOptions);
|
||||||
} catch (e) { // non-zero exit code
|
} catch (e) { // non-zero exit code
|
||||||
res.error = new Error(DEFAULT_ERR_MSG);
|
res.error = new Error(DEFAULT_ERR_MSG);
|
||||||
res.error.method = 'execFileSync';
|
res.error.method = 'execFileSync';
|
||||||
res.error.command = extScriptPath;
|
res.error.program = extHostPath;
|
||||||
res.error.args = cmdArgs;
|
res.error.args = hostArgs;
|
||||||
res.error.ExtMessage = e.stderr.trim();
|
res.error.extMessage = e.stderr.trim();
|
||||||
|
res.error.exitCode = e.status;
|
||||||
res.error.code = e.code;
|
res.error.code = e.code;
|
||||||
res.error.signal = e.signal;
|
res.error.signal = e.signal;
|
||||||
res.error.exitCode = e.status;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res = _execFileSync(cmdArgs, execOptions);
|
res = _execFileSync(options, execOptions);
|
||||||
}
|
}
|
||||||
if (!res.error) {
|
if (!res.error) {
|
||||||
res.input = res.input.replace(/^'|'$/g, '');
|
res.input = res.input.replace(/^'|'$/g, '');
|
||||||
|
@ -239,7 +243,7 @@ function readlineExt(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// piping via files (node v0.10-)
|
// piping via files (node v0.10-)
|
||||||
function _execFileSync(cmdArgs, execOptions) {
|
function _execFileSync(options, execOptions) {
|
||||||
|
|
||||||
function getTempfile(name) {
|
function getTempfile(name) {
|
||||||
var path = require('path'), filepath, suffix = '', fd;
|
var path = require('path'), filepath, suffix = '', fd;
|
||||||
|
@ -263,7 +267,7 @@ function _execFileSync(cmdArgs, execOptions) {
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
var execArgs, interpreter, res = {}, exitCode,
|
var hostArgs, shellPath, shellArgs, res = {}, exitCode,
|
||||||
pathStdout = getTempfile('readline-sync.stdout'),
|
pathStdout = getTempfile('readline-sync.stdout'),
|
||||||
pathStderr = getTempfile('readline-sync.stderr'),
|
pathStderr = getTempfile('readline-sync.stderr'),
|
||||||
pathExit = getTempfile('readline-sync.exit'),
|
pathExit = getTempfile('readline-sync.exit'),
|
||||||
|
@ -275,25 +279,27 @@ function _execFileSync(cmdArgs, execOptions) {
|
||||||
password = shasum.digest('hex');
|
password = shasum.digest('hex');
|
||||||
decipher = crypto.createDecipher(ALGORITHM_CIPHER, password);
|
decipher = crypto.createDecipher(ALGORITHM_CIPHER, password);
|
||||||
|
|
||||||
|
if (IS_WIN) { options.encoded = true; }
|
||||||
|
hostArgs = getHostArgs(options);
|
||||||
if (IS_WIN) {
|
if (IS_WIN) {
|
||||||
interpreter = process.env.ComSpec || 'cmd.exe';
|
shellPath = process.env.ComSpec || 'cmd.exe';
|
||||||
process.env.Q = '"'; // The quote (") that isn't escaped.
|
process.env.Q = '"'; // The quote (") that isn't escaped.
|
||||||
// `()` for ignore space by echo
|
// `()` for ignore space by echo
|
||||||
execArgs = ['/V:ON', '/S', '/C',
|
shellArgs = ['/V:ON', '/S', '/C',
|
||||||
'(%Q%' + interpreter + '%Q% /V:ON /S /C %Q%' +
|
'(%Q%' + shellPath + '%Q% /V:ON /S /C %Q%' +
|
||||||
'%Q%' + extHostPath + '%Q% //nologo %Q%' + extScriptPath + '%Q%' +
|
'%Q%' + extHostPath + '%Q%' +
|
||||||
cmdArgs.map(function(arg) { return ' %Q%' + arg + '%Q%'; }).join('') +
|
hostArgs.map(function(arg) { return ' %Q%' + arg + '%Q%'; }).join('') +
|
||||||
' & (echo !ERRORLEVEL!)>%Q%' + pathExit + '%Q%%Q%) 2>%Q%' + pathStderr + '%Q%' +
|
' & (echo !ERRORLEVEL!)>%Q%' + pathExit + '%Q%%Q%) 2>%Q%' + pathStderr + '%Q%' +
|
||||||
' |%Q%' + process.execPath + '%Q% %Q%' + __dirname + '\\encrypt.js%Q%' +
|
' |%Q%' + process.execPath + '%Q% %Q%' + __dirname + '\\encrypt.js%Q%' +
|
||||||
' %Q%' + ALGORITHM_CIPHER + '%Q% %Q%' + password + '%Q%' +
|
' %Q%' + ALGORITHM_CIPHER + '%Q% %Q%' + password + '%Q%' +
|
||||||
' >%Q%' + pathStdout + '%Q%' +
|
' >%Q%' + pathStdout + '%Q%' +
|
||||||
' & (echo 1)>%Q%' + pathDone + '%Q%'];
|
' & (echo 1)>%Q%' + pathDone + '%Q%'];
|
||||||
} else {
|
} else {
|
||||||
interpreter = extHostPath;
|
shellPath = extHostPath;
|
||||||
execArgs = ['-c',
|
shellArgs = ['-c',
|
||||||
// Use `()`, not `{}` for `-c` (text param)
|
// Use `()`, not `{}` for `-c` (text param)
|
||||||
'("' + extHostPath + '" "' + extScriptPath + '"' +
|
'("' + extHostPath + '"' +
|
||||||
cmdArgs.map(function(arg)
|
hostArgs.map(function(arg)
|
||||||
{ return " '" + arg.replace(/'/g, "'\\''") + "'"; }).join('') +
|
{ return " '" + arg.replace(/'/g, "'\\''") + "'"; }).join('') +
|
||||||
'; echo $?>"' + pathExit + '") 2>"' + pathStderr + '"' +
|
'; echo $?>"' + pathExit + '") 2>"' + pathStderr + '"' +
|
||||||
' |"' + process.execPath + '" "' + __dirname + '/encrypt.js"' +
|
' |"' + process.execPath + '" "' + __dirname + '/encrypt.js"' +
|
||||||
|
@ -302,11 +308,12 @@ function _execFileSync(cmdArgs, execOptions) {
|
||||||
'; echo 1 >"' + pathDone + '"'];
|
'; echo 1 >"' + pathDone + '"'];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
childProc.spawn(interpreter, execArgs, execOptions);
|
childProc.spawn(shellPath, shellArgs, execOptions);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.error = new Error(e.message);
|
res.error = new Error(e.message);
|
||||||
res.error.method = '_execFileSync - spawn';
|
res.error.method = '_execFileSync - spawn';
|
||||||
res.error.interpreter = interpreter;
|
res.error.program = shellPath;
|
||||||
|
res.error.args = shellArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fs.readFileSync(pathDone, {encoding: encoding}).trim() !== '1') {}
|
while (fs.readFileSync(pathDone, {encoding: encoding}).trim() !== '1') {}
|
||||||
|
@ -317,9 +324,9 @@ function _execFileSync(cmdArgs, execOptions) {
|
||||||
} else {
|
} else {
|
||||||
res.error = new Error(DEFAULT_ERR_MSG);
|
res.error = new Error(DEFAULT_ERR_MSG);
|
||||||
res.error.method = '_execFileSync';
|
res.error.method = '_execFileSync';
|
||||||
res.error.command = extScriptPath;
|
res.error.program = shellPath;
|
||||||
res.error.args = cmdArgs;
|
res.error.args = shellArgs;
|
||||||
res.error.ExtMessage = fs.readFileSync(pathStderr, {encoding: encoding}).trim();
|
res.error.extMessage = fs.readFileSync(pathStderr, {encoding: encoding}).trim();
|
||||||
res.error.exitCode = +exitCode;
|
res.error.exitCode = +exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +338,38 @@ function _execFileSync(cmdArgs, execOptions) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHostArgs(options) {
|
||||||
|
// To send any text to crazy Windows shell safely.
|
||||||
|
function encodeDOS(arg) {
|
||||||
|
return arg.replace(/[^\w\u0080-\uFFFF]/g, function(chr) {
|
||||||
|
return '#' + chr.charCodeAt(0) + ';';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return extHostArgs.concat((function(conf) {
|
||||||
|
var args = [], key;
|
||||||
|
for (key in conf) {
|
||||||
|
if (conf.hasOwnProperty(key)) {
|
||||||
|
if (conf[key] === 'boolean') {
|
||||||
|
if (options[key]) { args.push('--' + key); }
|
||||||
|
} else if (conf[key] === 'string') {
|
||||||
|
if (options[key] !== '') {
|
||||||
|
args.push('--' + key,
|
||||||
|
options.encoded ? encodeDOS(options[key]) : options[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
})({
|
||||||
|
display: 'string',
|
||||||
|
noEchoBack: 'boolean',
|
||||||
|
mask: 'string',
|
||||||
|
keyIn: 'boolean',
|
||||||
|
encoded: 'boolean'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// for dev
|
// for dev
|
||||||
exports._useExtSet = function(use) { useExt = use; };
|
exports._useExtSet = function(use) { useExt = use; };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue