🐛 fix: lambda closure crash + .bat version noise on Windows

Bug 1 — UartMonitorWindow crash on serial open failure:
- lambda: self._show_unavailable(str(e))  →  lambda e=e: ...
- Python 3 deletes 'e' after except block; default arg captures it

Bug 2 — xsct version shows 'ECHO 处于关闭状态。' on Windows:
- .bat wrappers output 'ECHO is off' / 'ECHO 处于关闭状态。' noise
- _is_batch_noise() filters known patterns (EN+ZH)
- Version regex now scans all output lines, skipping noise lines
- Path-based fallback (2023.2) catches any remaining undetectable cases
This commit is contained in:
2026-06-11 15:18:08 +08:00
parent 70c88815cc
commit da94cc6cdc
2 changed files with 29 additions and 10 deletions
+1 -1
View File
@@ -1079,7 +1079,7 @@ class UartMonitorWindow(ctk.CTkToplevel):
ser.close() ser.close()
self.after(0, self._on_open_success) self.after(0, self._on_open_success)
except Exception as e: except Exception as e:
self.after(0, lambda: self._show_unavailable(str(e))) self.after(0, lambda e=e: self._show_unavailable(str(e)))
threading.Thread(target=_bg_open, daemon=True).start() threading.Thread(target=_bg_open, daemon=True).start()
+26 -7
View File
@@ -324,7 +324,7 @@ def _get_tool_version(tool_path: str) -> str:
"""Get the version string from a tool executable. """Get the version string from a tool executable.
Tries (in order): Tries (in order):
1. tool -version 1. tool -version → parse version from output
2. Extract from path (e.g., .../Vitis/2023.2/bin/xsct → 2023.2) 2. Extract from path (e.g., .../Vitis/2023.2/bin/xsct → 2023.2)
Args: Args:
@@ -343,14 +343,17 @@ def _get_tool_version(tool_path: str) -> str:
) )
output = (result.stdout + result.stderr).strip() output = (result.stdout + result.stderr).strip()
if output: if output:
# Look for a version pattern in output # Scan all lines for a version pattern (skip batch echo noise)
m = re.search(r"(\d{4}\.\d+(?:\.\d+)?)", output) for raw_line in output.splitlines():
line = raw_line.strip()
if not line:
continue
# Skip Windows batch echo noise
if _is_batch_noise(line):
continue
m = re.search(r"(\d{4}\.\d+(?:\.\d+)?)", line)
if m: if m:
return m.group(1) return m.group(1)
# Return first meaningful line (truncated)
line = output.split("\n")[0][:80]
if line and "usage" not in line.lower():
return line
except (subprocess.TimeoutExpired, OSError): except (subprocess.TimeoutExpired, OSError):
pass pass
@@ -358,6 +361,22 @@ def _get_tool_version(tool_path: str) -> str:
return _version_from_path(tool_path) return _version_from_path(tool_path)
def _is_batch_noise(line: str) -> bool:
"""Check if a line is Windows batch script noise.
Args:
line: A line of output text.
Returns:
True if the line looks like batch echo/status noise.
"""
noise_patterns = [
r"^ECHO\s+(is\s+(on|off)|处于)", # ECHO is on/off (en+zh)
r"^[A-Z]:\\[^>]*>", # Prompt line like C:\path>
]
return any(re.search(p, line, re.IGNORECASE) for p in noise_patterns)
# ── Main check function ────────────────────────────────────────────── # ── Main check function ──────────────────────────────────────────────