fix: CLIXML-Fehler bei Remote-Tool-Ausführung auf Windows beheben
Statt powershell.exe als Kindprozess mit 2>&1 zu starten (was CLIXML-Parsing-Fehler bei rohem stderr verursacht), wird System.Diagnostics.Process direkt verwendet. Zusätzlich werden harmlose CLIXML-Progress-Meldungen aus stderr herausgefiltert. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f03fbd298e
commit
55477742a9
1 file changed
+29
-9
+29
-9
@@ -117,21 +117,41 @@ try {
|
||||
$stderr = ""
|
||||
|
||||
try {
|
||||
# EncodedCommand umgeht alle Quoting-Probleme (Anführungszeichen, Sonderzeichen)
|
||||
# Process direkt starten um CLIXML-Parsing-Fehler bei stderr zu vermeiden
|
||||
$encodedCmd = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($command))
|
||||
$output = & powershell.exe -NoProfile -NonInteractive -EncodedCommand $encodedCmd 2>&1
|
||||
$stdoutLines = @($output | Where-Object { $_ -isnot [System.Management.Automation.ErrorRecord] })
|
||||
$stderrLines = @($output | Where-Object { $_ -is [System.Management.Automation.ErrorRecord] }) |
|
||||
ForEach-Object { $_.ToString() }
|
||||
$stdout = ($stdoutLines | Out-String).TrimEnd()
|
||||
$stderr = ($stderrLines | Out-String).TrimEnd()
|
||||
$exitCode = $LASTEXITCODE
|
||||
if ($null -eq $exitCode) { $exitCode = 0 }
|
||||
$proc = New-Object System.Diagnostics.Process
|
||||
$proc.StartInfo.FileName = "powershell.exe"
|
||||
$proc.StartInfo.Arguments = "-NoProfile -NonInteractive -EncodedCommand $encodedCmd"
|
||||
$proc.StartInfo.RedirectStandardOutput = $true
|
||||
$proc.StartInfo.RedirectStandardError = $true
|
||||
$proc.StartInfo.UseShellExecute = $false
|
||||
$proc.StartInfo.CreateNoWindow = $true
|
||||
$proc.Start() | Out-Null
|
||||
# stderr async lesen um Deadlocks zu vermeiden
|
||||
$stderrTask = $proc.StandardError.ReadToEndAsync()
|
||||
$stdout = $proc.StandardOutput.ReadToEnd()
|
||||
$stderrTask.Wait()
|
||||
$stderr = $stderrTask.Result
|
||||
$proc.WaitForExit()
|
||||
$exitCode = $proc.ExitCode
|
||||
$proc.Dispose()
|
||||
} catch {
|
||||
$stderr = $_.Exception.Message
|
||||
$exitCode = 1
|
||||
}
|
||||
|
||||
# CLIXML-Progress aus stderr filtern (PowerShell schreibt Modul-Lade-Fortschritt als CLIXML)
|
||||
if ($stderr -and $stderr.StartsWith("#< CLIXML")) {
|
||||
$cleanLines = @()
|
||||
foreach ($line in ($stderr -split "`n")) {
|
||||
$trimmed = $line.Trim()
|
||||
if ($trimmed -eq "#< CLIXML") { continue }
|
||||
if ($trimmed -match '^\<Objs .+\<PR N="Record"\>.*\<T\>Completed\</T\>') { continue }
|
||||
if ($trimmed -ne "") { $cleanLines += $line }
|
||||
}
|
||||
$stderr = ($cleanLines -join "`n").Trim()
|
||||
}
|
||||
|
||||
# Ergebnis senden
|
||||
$response = @{
|
||||
type = "result"
|
||||
|
||||
Reference in new issue
Block a user