Compare commits

..
Author SHA1 Message Date
l0ng-ai 0b0586a71a fix(windows): don't show system error boxes for processes that fail to load
A broken python.exe found while detecting interpreters made Windows show a
modal "System Error" box ("VCRUNTIME140.dll was not found"). The app now
sets SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX at startup; child
processes inherit the error mode, so such a probe fails with an exit code.

Fixes #1161
2026-11-10 23:28:53 +08:00
4 changed files with 17 additions and 13 deletions

No files matched your search

+1
View File
@@ -107,6 +107,7 @@ windows = { version = "0.62", features = [
windows-sys = { version = "0.61", features = [
"Win32_Foundation",
"Win32_Graphics_Gdi",
"Win32_System_Diagnostics_Debug",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
] }
+15
View File
@@ -71,6 +71,8 @@ pub fn export_bindings(builder: &tauri_specta::Builder<tauri::Wry>) {
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
ide_workspace::process::mark_start();
#[cfg(windows)]
quiet_error_dialogs();
let context = tauri::generate_context!();
#[cfg(debug_assertions)]
let context = dev::configure(context);
@@ -389,3 +391,16 @@ pub(crate) fn dispatch_menu_action(app: &tauri::AppHandle, id: &str) {
},
}
}
/// Windows shows a modal "System Error" box when a process can't load a DLL (a broken
/// `python.exe` found while detecting interpreters: "VCRUNTIME140.dll was not found").
/// Child processes inherit the error mode, so probes and tools started by the IDE fail
/// with an exit code instead (#1161).
#[cfg(windows)]
fn quiet_error_dialogs() {
use windows_sys::Win32::System::Diagnostics::Debug::{
SEM_FAILCRITICALERRORS, SEM_NOOPENFILEERRORBOX, SetErrorMode,
};
// SAFETY: SetErrorMode only changes this process's error mode flags.
unsafe { SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX) };
}
@@ -134,11 +134,6 @@ describe("debug tool window", () => {
expect(console.getAttribute("aria-selected")).toBe("true");
act(() => useDebug.setState({ sessions: { 1: session } }));
expect(variables.getAttribute("aria-selected")).toBe("true");
// Stepping from the Console keeps it in front.
fireEvent.click(console);
act(() => useDebug.setState({ sessions: { 1: { ...session, status: "running" } } }));
act(() => useDebug.setState({ sessions: { 1: { ...session, stopReason: "step" } } }));
expect(console.getAttribute("aria-selected")).toBe("true");
});
it("renders session tabs, views, frames and typed variables", async () => {
+1 -8
View File
@@ -153,14 +153,7 @@ export function DebugToolWindow() {
setView({
session: active.startedAt,
status: active.status,
// A breakpoint or exception brings Threads & Variables to the front; finishing a step keeps
// the tab the user is on (e.g. Console, to watch the output while stepping).
tab:
active.status === "starting"
? "console"
: active.status === "paused" && active.stopReason !== "step"
? "variables"
: view.tab,
tab: active.status === "starting" ? "console" : active.status === "paused" ? "variables" : view.tab,
});
const tab = view.tab;