5

Some useful info beforehand. What I'm attempting to do is read in output from an external command, specifically steamcmd, using powershell start-process and System.diagnostics.ProcessStartInfo.

What I'm running into is RedirectStandardOutput buffer limit of 4096 bytes. The output I'm getting from the steamcmd is more than that buffer, so I'm only getting a portion of what I need. I have no other method for getting this data, other than calling steamcmd.

You can see the output as well if you have steamcmd (it's free) and running this.

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

This will download all the manifest info about that appid.

I've tried to redirect to a file and also to a variable, both work as expected, it's just that it's cut short by the buffer. There also doesn't appear to be a powershell method in System.Diagnostics.Process to wait for the OutputDataReceived event.

Code used (stolen from another STackOverflow question)

$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

I think the actual issue is that steamCMD just outputs in one big write instead of line by line. I guess a better question would be, how can I increase the standardoutput buffer size of Start-Process or System.Diagnostics.Process.

Note: running the steamcmd > somefile.txt results in same buffer limit.

1 Answers1

2

steamcmd.exe appears to work properly only if run from an empty subdirectory, at least for this command line.

I can't explain it, but I was able to repro your issue when I rand the command twice.

Here is one way to work around the issue. Run steamcmd.exe from an empty directory. Depending on your needs, you could use a static temp dir and clean it before each run, or generate a temp dir and use that and decide how to clean it up later.

CODE

$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'"
Kory Gill
  • 6,993
  • 1
  • 25
  • 33
  • That still won't work because of the stdout buffer limit. It's all hinging on the 4096 buffer and finding a way to grab more than that or control it so you can read it line by line before steamcmd exits. – Rudger_Wolvram Feb 27 '17 at 04:10
  • I get no errors doing this on my machine. PSVersion 5.1.14393.693. Saved the output to a file, it's 269 lines long and 13KB in size. – Kory Gill Feb 27 '17 at 17:25
  • When I do it in PS 4,0 mine stops at 221 lines and 5k, regardless of method or file output. When I do it through straight cmd and > tofile.txt, it's 221 lines. When i run it without redirected output in cmd and copy all the text manually to a file I get 327 lines and 15k size. Edit: also tried with commandprompt portable from portableapps.com, same 221 line/5k limit. – Rudger_Wolvram Feb 27 '17 at 17:40
  • Just upgraded to WMF 5.1 with PS version 5.1.14409.1005, still no dice, getting 220 lines back, still not the entire thing. :/ – Rudger_Wolvram Feb 28 '17 at 02:38
  • I've got a crap fix, and it's not an actual answer, so it's going to be a comment. I worked around the problem by using a linux server that has a website hosted off it. Using the linux steamcmd and > to a file on the public website. I then use Invoke-WebRequest to pull the data down. It's hacky, but it works until I can find out why windows hates what I'm attempting. – Rudger_Wolvram Feb 28 '17 at 05:35
  • That still doesn't work on my end, it takes the truncated data generated by appinfo and adds all the information to the end about downloading update data and applying the update to steamcmd. I'm getting back 240 lines instead of the normal 221 because of additional download info, actual data is 335 lines. – Rudger_Wolvram Mar 01 '17 at 02:36