我在PowerShell中有一组脚本。我使用.HTA构建了一个GUI,但我正在迁移到类似于NODE.js的方法。
我有一个工作脚本,但我必须进行修改以解决丢失的功能以从命令行获取输入。我以前会看到CMD提示窗口,我会看到所有输出,如果有提示(Read-Host
),用户可以与它进行交互。为了解决这个问题,我现在使用[Microsoft.VisualBasic.Interaction]::InputBox()
在需要时从用户那里获得输入。
我在尝试使用child.stdin.write();
时遇到问题,因为我的PowerShell进程只是挂起。它不会回应我的意见。
我已经尝试过我在网上找到的每一个答案,但没有成功。在生产中调用的脚本是一个长时间运行的过程,具体取决于所选的任务,它将花费20分钟到3个小时。
所以,问题是,我无法让child.spawned进程发送输入,或者PowerShell不接受来自stdin的输入。
提前感谢您的帮助。
代码:
HTML:
<button type="button" id="btn_ExecuteReport">Run Report</button>
<button type="button" id="btn_StopReport" >Stop Report</button>
<button type="button" id="btn_SendInput" >Send this...</button>
<h2>Results:</h2>
<p id="result_id">...</p>
<br/>
JS(使用Electron v 0.31.0,io.js v 3.1.0,jQuery v 1.7.2):
$(document).ready(function () {
$("#btn_ExecuteReport").click(function (event) {
event.stopPropagation();
global.$ = $;
var remote = require('remote');
// to get some paths depending on OS
var app = remote.require('app');
//clipboard
var clipboard = require('clipboard');
var shell = require('shell');
// for choosing a folder
var dialog = remote.require('dialog');
var spawn = require('child_process').spawn;
sCmd = "powershell.exe ";
sCmdArg = '&' + "'" + __dirname + "/app.ps1' " ;
// omit parameters for the purpose of this example
// + "-ODir '" + sOutputDirectory
// + "' -WDir '" + sWorkingDirectory + "'"
// + " -Report " + sReport
// + " -pSendEmail " + sSendEmail
// + " -pSendEmailHTMLBody " + sSendEmailHTMLBody
// + " -pCreateReport " + sCreateReport
// + " -pCheckReport " + sCheckReport
// + " -pEmailAction " + sEmailAction
// ;
$("#result_id").html("<p><font color='magenta'>Command: </font>"
+ sCmdConcat + "</p>");
// try again with spawn and event handlers
var psSpawn = spawn(sCmd, [sCmdArg]);
// add a 'data' event listener for the spawn instance
psSpawn.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
// add an 'end' event listener to close the writeable stream
psSpawn.stdout.on('end', function(data) {
console.log('Done with psSpawn...' );
});
psSpawn.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
// when the spawn child process exits, check if there were any errors and close the writeable stream
psSpawn.on('exit', function(code) {
if (code != 0) {
console.log('[EXIT] Failed: ' + code);
}
//Collect result from PowerShell (via clipboard)
sResultData = clipboard.readText("Text");
});
psSpawn.on('close', function(code) {
if (code != 0) {
console.log('[ISSUE] code: ' + code);
}
console.log('[CLOSE]');
});
//sending the input with button #btn_sendInput
$("#btn_SendInput").click(function (event) {
psSpawn.stdin.setEncoding('utf8');
psSpawn.stdin.write('ok');
psSpawn.stdin.write('\n');
psSpawn.stdin.write(os.EOL);
//uncomment following line to end stdin on first button press
//psSpawn.stdin.end();
});
// killing process
$("#btn_StopReport").click(function (event) {
event.stopPropagation();
psSpawn.kill('SIGTERM');
console.log('killed ' + psSpawn.pid);
});
});
});
PowerShell:
#work around to lack of Read-Host functionality
Write-Host "waiting"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$computer = [Microsoft.VisualBasic.Interaction]::InputBox("Enter a computer name", "Computer", "$env:computername")
#
Write-Host "[Done] waiting"
#workaround END works
Write-Host "Computer: [$computer]"
# START omit ----------------
#if we remove the following lines, all works but we lose the functionality to ask for input from the command line
Write-Host "Propmt for OK"
$ok = Read-Host
#
Write-Host "Prompt. Value of 'ok': [$ok]"
# END omit ----------------
#Copy new message to clipboard
"we want to see this maessage on the browser. $computer" | clip
#Exit script returning the appropriate value
[Environment]::Exit(0)
exit
我的console
输出为:
stdout: waiting
stdout:
stdout: [Done] waiting
Computer: [COMPUTER_NAME]
Propmt for OK
无论我按Send this...
多少次,脚本都会动手。 console
输出是(在按下#buton_StopReport
之后):
killed 2548
Done with psSpawn...
[EXIT] Failed: null
[ISSUE] code: null
[CLOSE]