From 6954ac79678d19b01984f1ddba2e17fc4cbfd0df Mon Sep 17 00:00:00 2001 From: master <> Date: Fri, 13 Mar 2026 13:59:00 +0200 Subject: [PATCH] Use cmd-based redirection in scratch runner --- scripts/run-clean-scratch-iterations.ps1 | 80 ++++++++---------------- 1 file changed, 25 insertions(+), 55 deletions(-) diff --git a/scripts/run-clean-scratch-iterations.ps1 b/scripts/run-clean-scratch-iterations.ps1 index 19f7d1912..6bc23bfb2 100644 --- a/scripts/run-clean-scratch-iterations.ps1 +++ b/scripts/run-clean-scratch-iterations.ps1 @@ -78,6 +78,8 @@ function Invoke-External { ) Push-Location $WorkingDirectory + $stdoutPath = New-LogCapturePath -Suffix '.stdout.log' + $stderrPath = New-LogCapturePath -Suffix '.stderr.log' try { $resolvedFilePath = $FilePath if (Test-Path $FilePath) { @@ -93,76 +95,44 @@ function Invoke-External { $startArgumentList = @('-NoLogo', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $resolvedFilePath) + @($ArgumentList) } - $startInfo = [System.Diagnostics.ProcessStartInfo]::new() - $startInfo.FileName = $startFilePath - $startInfo.Arguments = (($startArgumentList | ForEach-Object { Format-ProcessArgument -Value ([string]$_) }) -join ' ') - $startInfo.WorkingDirectory = $WorkingDirectory - $startInfo.UseShellExecute = $false - $startInfo.RedirectStandardOutput = $true - $startInfo.RedirectStandardError = $true + $commandLine = (@((Format-ProcessArgument -Value $startFilePath)) + @($startArgumentList | ForEach-Object { Format-ProcessArgument -Value ([string]$_) })) -join ' ' + $redirectedCommand = '{0} 1>{1} 2>{2}' -f $commandLine, (Format-ProcessArgument -Value $stdoutPath), (Format-ProcessArgument -Value $stderrPath) + $cmdPath = (Get-Command cmd.exe -ErrorAction Stop).Source + $cmdArguments = @('/d', '/s', '/c', $redirectedCommand) - $process = [System.Diagnostics.Process]::new() - $process.StartInfo = $startInfo + $process = Start-Process ` + -FilePath $cmdPath ` + -ArgumentList $cmdArguments ` + -WorkingDirectory $WorkingDirectory ` + -PassThru - $stdoutQueue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new() - $stderrQueue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new() + $stdoutIndex = 0 + $stderrIndex = 0 - $stdoutHandler = [System.Diagnostics.DataReceivedEventHandler]{ - param($sender, $eventArgs) - if ($null -ne $eventArgs.Data) { - $stdoutQueue.Enqueue($eventArgs.Data) - } - } - - $stderrHandler = [System.Diagnostics.DataReceivedEventHandler]{ - param($sender, $eventArgs) - if ($null -ne $eventArgs.Data) { - $stderrQueue.Enqueue($eventArgs.Data) - } - } - - $process.add_OutputDataReceived($stdoutHandler) - $process.add_ErrorDataReceived($stderrHandler) - - if (-not $process.Start()) { - throw "Failed to start process: $resolvedFilePath" - } - - $process.BeginOutputReadLine() - $process.BeginErrorReadLine() - - $dequeuedLine = $null while (-not $process.HasExited) { - while ($stdoutQueue.TryDequeue([ref]$dequeuedLine)) { - $dequeuedLine | Out-Host - $dequeuedLine = $null - } - - while ($stderrQueue.TryDequeue([ref]$dequeuedLine)) { - $dequeuedLine | Out-Host - $dequeuedLine = $null - } - + Write-LogCaptureDelta -Path $stdoutPath -LineIndex ([ref]$stdoutIndex) + Write-LogCaptureDelta -Path $stderrPath -LineIndex ([ref]$stderrIndex) Start-Sleep -Milliseconds 500 + $process.Refresh() } $process.WaitForExit() + $process.Refresh() - while ($stdoutQueue.TryDequeue([ref]$dequeuedLine)) { - $dequeuedLine | Out-Host - $dequeuedLine = $null - } - - while ($stderrQueue.TryDequeue([ref]$dequeuedLine)) { - $dequeuedLine | Out-Host - $dequeuedLine = $null - } + Write-LogCaptureDelta -Path $stdoutPath -LineIndex ([ref]$stdoutIndex) + Write-LogCaptureDelta -Path $stderrPath -LineIndex ([ref]$stderrIndex) if ($process.ExitCode -ne 0) { throw "Command failed: $resolvedFilePath $($ArgumentList -join ' ')" } } finally { + foreach ($capturePath in @($stdoutPath, $stderrPath)) { + if (Test-Path $capturePath) { + Remove-Item $capturePath -Force -ErrorAction SilentlyContinue + } + } + Pop-Location } }