Node.js 使用PowerShell Invoke命令和进程将标准输出显示在控制台上

Node.js 使用PowerShell Invoke命令和进程将标准输出显示在控制台上,node.js,windows,powershell,Node.js,Windows,Powershell,我有一个使用Invoke命令的Powershell脚本。下面是正在调用的代码: $scriptblock = { $process = New-Object system.Diagnostics.Process $si = New-Object System.Diagnostics.ProcessStartInfo $si.FileName = $cmd $si.Arguments = $cmd_args $si.UseShellExecute = false $si.

我有一个使用Invoke命令的Powershell脚本。下面是正在调用的代码:

$scriptblock = {
  $process = New-Object system.Diagnostics.Process

  $si = New-Object System.Diagnostics.ProcessStartInfo
  $si.FileName = $cmd
  $si.Arguments = $cmd_args
  $si.UseShellExecute = false
  $si.RedirectStandardOutput = true

  $process.StartInfo = $si
  $process.Start()
  $processId = $process.Id
  $process.WaitForExit()
}

Invoke-Command -ScriptBlock $scriptblock
该问题与从PowerShell窗口运行脚本时将进程的标准输出显示到PowerShell控制台有关

现在,我确信可执行文件$cmd会发送到stdout,因为当我使用cmd.exe运行可执行文件时,它会显示到该控制台的输出。当我从NodeJS脚本调用此Powershell脚本时,我还能够成功重定向输出,如下所示:

var exec  = require('child_process').exec,
var cmd   = 'powershell -ExecutionPolicy Bypass "' + launch_cmd + " \'" + ver + "\'\"";

console.log("\n\tUsing command for NodeJS child process:\n\t\t" + cmd + "\n\n")
child = exec(cmd, { cwd : prj }, function(stdout, stderr){});

child.stdout.on("data",function(data){
    process.stdout.write(data);
});

child.stderr.on("data",function(data){
    process.stderr.write(data);
});

child.on("exit",function(){
    console.log("\n\nFinished Process");
});
我希望能够将标准输出获取到PowerShell控制台。我在脚本块中查看并尝试了以下操作,但没有成功:

$scriptblock = {
  $process = New-Object system.Diagnostics.Process

  $si = New-Object System.Diagnostics.ProcessStartInfo
  $si.FileName = $cmd
  $si.Arguments = $cmd_args
  $si.UseShellExecute = false
  $si.RedirectStandardOutput = true

  $process.StartInfo = $si
  $process.Start()
  $process.BeginOutputReadLine()
  $process.StandardOutput.ReadToEnd()
  $processId = $process.Id
  $process.StandardOutput
  $process.WaitForExit()
}

Invoke-Command -ScriptBlock $scriptblock

关于如何使进程向PowerShell控制台显示其标准输出的任何建议?

您需要不断读取标准输出流,直到进程退出才能获取所有内容:

$scriptblock = {

    param($cmd, $cmd_args)

    $process = New-Object system.Diagnostics.Process

    $si = New-Object System.Diagnostics.ProcessStartInfo
    $si.FileName = $cmd
    $si.Arguments = $cmd_args
    $si.UseShellExecute = $false
    $si.RedirectStandardOutput = $true

    $process.StartInfo = $si
    $process.Start() | Out-Null

    do{ # Keep redirecting output until process exits
        Write-Host $process.StandardOutput.ReadLine()
    } until ($process.HasExited)
}

Invoke-Command -ScriptBlock $scriptblock -ArgumentList "cmd.exe","/c echo test1 & echo test2 & ping 127.0.0.1 -n 3 > nul & echo test3"

您将看到输出流被实时复制到主机。如果您想将结果传递到管道中,也可以使用
写入输出
,您必须将streamreader分配给$process.StandardOutput,正如您链接的technet所示。此页面:表示您可以这样做:$stdout=$p.StandardOutput.ReadToEnd()$stderr=$p.StandardError.ReadToEnd()漂亮!非常感谢你,马西亚斯。你的代码完美地解决了这个问题。我想我现在的问题是,为什么Node能够显示输出,而Powershell却不能?因为您在nodejs示例中主动订阅了流上的“数据”事件。在PowerShell中也可以这样做,但我认为对于95%的用例,这种方法(
do{}until($process.HasExited)
)可能就足够了(更简单、更干净):)