@@ -149,72 +149,45 @@ function Invoke-External {
149149 [string ]$WorkingDirectory
150150 )
151151
152- # Prepare argument string
152+ # Build argument string
153153 $argLine = ($Arguments | ForEach-Object {
154154 if ($_ -match ' \s' ) { ' "{0}"' -f $_ } else { $_ }
155155 }) -join ' '
156156
157- # Setup PSI
158- $psi = New-Object System.Diagnostics.ProcessStartInfo
159- $ext = [System.IO.Path ]::GetExtension($Exe )
160-
161- if ($ext -and ($ext.ToLower () -in @ (" .cmd" , " .bat" ))) {
162- $psi.FileName = " cmd.exe"
163- $psi.Arguments = " /c `" $Exe `" $argLine "
164- } else {
165- $psi.FileName = $Exe
166- $psi.Arguments = $argLine
167- }
168-
169- $psi.UseShellExecute = $false
170- $psi.RedirectStandardOutput = $true
171- $psi.RedirectStandardError = $true
172- $psi.CreateNoWindow = $true
173- $psi.WorkingDirectory = $ (if ($WorkingDirectory ) { $WorkingDirectory } else { (Get-Location ).Path })
174-
175- # Start process
176- $p = New-Object System.Diagnostics.Process
177- $p.StartInfo = $psi
178-
179- # Buffers to store output
180- $stdout = New-Object System.Text.StringBuilder
181- $stderr = New-Object System.Text.StringBuilder
182-
183- # Event handlers (very stable compared to ObjectEvent)
184- $p.add_OutputDataReceived ({
185- if ($_.Data ) { [void ]$stdout.AppendLine ($_.Data ) }
186- })
187- $p.add_ErrorDataReceived ({
188- if ($_.Data ) { [void ]$stderr.AppendLine ($_.Data ) }
189- })
190-
191- [void ]$p.Start ()
192-
193- # Begin async reads (no deadlock)
194- $p.BeginOutputReadLine ()
195- $p.BeginErrorReadLine ()
196-
197- # Wait without blocking streams (safe!)
198- while (-not $p.HasExited ) {
199- Start-Sleep - Milliseconds 100
200- }
201-
202- # Logging
157+ # Prepare temp output files (prevents ALL hangs)
158+ $outFile = [IO.Path ]::GetTempFileName()
159+ $errFile = [IO.Path ]::GetTempFileName()
160+
161+ # Start the external process
162+ $process = Start-Process `
163+ - FilePath $Exe `
164+ - ArgumentList $argLine `
165+ - RedirectStandardOutput $outFile `
166+ - RedirectStandardError $errFile `
167+ - PassThru `
168+ - NoNewWindow `
169+ - Wait `
170+ - WorkingDirectory $ (if ($WorkingDirectory ) { $WorkingDirectory } else { (Get-Location ).Path })
171+
172+ # Read output AFTER process exits (safe)
173+ $stdout = Get-Content $outFile - Raw - ErrorAction SilentlyContinue
174+ $stderr = Get-Content $errFile - Raw - ErrorAction SilentlyContinue
175+
176+ # Write logs if needed
203177 if ($LogFile ) {
204178 $logDir = Split-Path $LogFile - Parent
205179 if ($logDir -and ! (Test-Path $logDir )) {
206180 New-Item - ItemType Directory - Path $logDir - Force | Out-Null
207181 }
208182
209- if ($stdout.Length -gt 0 ) { Add-Content $LogFile $stdout.ToString () }
210- if ($stderr.Length -gt 0 ) { Add-Content $LogFile $stderr.ToString () }
183+ if ($stdout ) { Add-Content $LogFile $stdout }
184+ if ($stderr ) { Add-Content $LogFile $stderr }
211185 }
212186
213- return $p .ExitCode
187+ return $process .ExitCode
214188}
215189
216190
217-
218191function Get-MavenCommand {
219192 param ([Parameter (Mandatory )][string ]$RepoDir )
220193 $mvnCmd = Get-Command mvn - ErrorAction SilentlyContinue
0 commit comments