Powershell 标准输出缓冲区对于外部命令来说太小

标签 powershell stdout streamreader redirectstandardoutput

预先提供一些有用的信息。我试图做的是使用 powershell start-process 和 System.diagnostics.ProcessStartInfo 从外部命令(特别是 steamcmd)读取输出。

我遇到的是 RedirectStandardOutput 缓冲区限制为 4096 字节。我从 steamcmd 获得的输出超出了该缓冲区,因此我只获得了我需要的一部分。除了调用 steamcmd 之外,我没有其他方法来获取此数据。

如果您有 steamcmd(免费)并运行它,您也可以看到输出。

steamcmd +login anonymous +app_info_update 1 +app_info_print 443030 +quit

这将下载有关该 appid 的所有 list 信息。

我尝试重定向到一个文件和一个变量,两者都按预期工作,只是它被缓冲区缩短了。 System.Diagnostics.Process 中似乎也没有用于等待 OutputDataReceived 事件的 powershell 方法。

使用的代码(从另一个 STackOverflow 问题中窃取)

$psi = New-object System.Diagnostics.ProcessStartInfo 
$psi.CreateNoWindow = $true 
$psi.UseShellExecute = $false 
$psi.RedirectStandardOutput = $true 
$psi.RedirectStandardError = $true 
$psi.FileName = "C:\Path\to\SteamCMD.exe"
$psi.Arguments = "+login anonymous +app_info_update 1 +app_info_print 443030 +quit"
$process = New-Object System.Diagnostics.Process 
$process.StartInfo = $psi 
[void]$process.Start()
$output = $process.StandardOutput.ReadToEnd()
$process.WaitForExit() 
$output

我认为实际的问题是 steamCMD 仅以一次大写入而不是逐行输出。我想更好的问题是,如何增加 Start-Process 或 System.Diagnostics.Process 的标准输出缓冲区大小。

注意:运行 steamcmd > somefile.txt 会产生相同的缓冲区限制。

最佳答案

只有从空子目录运行时,steamcmd.exe 才能正常工作,至少对于此命令行而言是如此。

我无法解释它,但当我运行该命令两次时,我能够重现您的问题。

这是解决该问题的一种方法。从空目录运行 steamcmd.exe。根据您的需要,您可以使用静态临时目录并在每次运行之前清理它,或者生成一个临时目录并使用它并决定稍后如何清理它。

代码

$steamcmd = "L:\test\steam\steamcmd.exe"

# steam works best if run in an empty directory
# why, i have no clue...

$tempName = [System.IO.Path]::GetRandomFileName()
$parentDir = Split-Path $steamcmd -Parent
$tempPath = Join-Path $parentDir $tempName
$null = New-Item $tempPath -ItemType Directory
$null = Copy-Item $steamcmd $tempPath

Write-Output "temp directory is '$tempPath'"

$steamcmdTemp = Join-Path $tempPath 'steamcmd.exe'

Write-Output "Running '$steamcmdTemp'..."
$output = & $steamcmdTemp +login anonymous +app_info_update 1 +app_info_print 443030 +quit

$now = [DateTime]::Now.ToString("yyyyMMdd HHmmss")
$outFile = "output {0}.txt" -f $now
$outputFile = Join-Path $parentDir $outFile

Write-Output "Saving output to '$outputFile'"
$output | Out-File $outputFile -Force


# todo: deal with removing the temp dir...
# or keep cleaning and reusing a static name...

Write-Output "Remember to cleanup '$tempPath'"

关于Powershell 标准输出缓冲区对于外部命令来说太小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42475938/

相关文章:

powershell - 如何在 PowerShell 上更改字体

c - freopen 标准输出和控制台

c# - 在 asp.net MVC 中读取文本文件时出错

c# - 加快 StreamReader 的搜索/读取速度

用于将组从静态更改为动态的 Powershell AzureAD 脚本

powershell - Powershell,多行文本文件变量

基于新线的Powershell Split

python - 将 sys.stdout 作为参数传递给进程

bash - 如何同步记录 stderr 和 stdout,但仅将 stderr 打印到屏幕?

java - 如何在不先将它们附加到 StringBuilder 的情况下从一堆字符串中创建一个读取器?