[CmdletBinding()] param( [Parameter(Mandatory=$true)][string]$ExecutableName, [Parameter(Mandatory=$true)][string[]]$ExecutableArguments, [Parameter(Mandatory=$true)][string]$LogStem ) $ErrorActionPreference = 'Stop' $RoundDir = [IO.Path]::GetFullPath($PSScriptRoot) $StandaloneRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..\..')) if ([IO.Path]::GetFileName($ExecutableName) -ne $ExecutableName) { throw 'ExecutableName must be a filename.' } if ([IO.Path]::GetFileName($LogStem) -ne $LogStem) { throw 'LogStem must be a filename stem.' } $ExecutablePath = Join-Path (Join-Path $StandaloneRoot 'bin') $ExecutableName if (-not (Test-Path -LiteralPath $ExecutablePath -PathType Leaf)) { throw "Executable not found: $ExecutablePath" } $StdoutPath = Join-Path $RoundDir ($LogStem + '.stdout.log') $StderrPath = Join-Path $RoundDir ($LogStem + '.stderr.log') $HostProcess = Get-Process -Id $PID $HostProcess.PriorityClass = 'Normal' $HostProcess.ProcessorAffinity = [IntPtr]0xFFFF $RunClock = [Diagnostics.Stopwatch]::StartNew() $Child = Start-Process -FilePath $ExecutablePath -ArgumentList $ExecutableArguments ` -WorkingDirectory $StandaloneRoot -WindowStyle Hidden -PassThru ` -RedirectStandardOutput $StdoutPath -RedirectStandardError $StderrPath $PeakWorkingSet = 0L $PeakPrivateMemory = 0L while (-not $Child.HasExited) { $Child.Refresh() if ($Child.HasExited) { break } $Child.PriorityClass = 'Normal' $Child.ProcessorAffinity = [IntPtr]0xFFFF $PeakWorkingSet = [Math]::Max($PeakWorkingSet,$Child.WorkingSet64) $PeakPrivateMemory = [Math]::Max($PeakPrivateMemory,$Child.PrivateMemorySize64) Start-Sleep -Milliseconds 50 } $Child.WaitForExit() $RunClock.Stop() $Child.Refresh() Write-Output "RUN_EXIT pid=$($Child.Id) priority=Normal affinity=0xFFFF wall_s=$([math]::Round($RunClock.Elapsed.TotalSeconds,3)) peak_working_set_gb=$([math]::Round($PeakWorkingSet/1GB,2)) peak_private_gb=$([math]::Round($PeakPrivateMemory/1GB,2)) cpu_s=$([math]::Round($Child.CPU,3)) exit_code=$($Child.ExitCode)" exit $Child.ExitCode