diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/agent_db.rs b/apps/ai-game-creator-shell/src-tauri/src/project/agent_db.rs index bb3039585..0bce5df4a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/agent_db.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/agent_db.rs @@ -3714,6 +3714,22 @@ fn try_open_project_append_os_lock(path: &Path, error_label: &str) -> Result Result<(), String> { + drop(held_lock); + crate::secure_windows_game_creator_path_for_current_user_with_auto_elevation(path, false, true) + .map_err(|repair_error| format!("{strict_error};自动提权修复未完成:{repair_error}")) +} + #[cfg(windows)] fn try_open_project_append_os_lock(path: &Path, error_label: &str) -> Result, String> { use std::os::windows::fs::OpenOptionsExt; @@ -3733,15 +3749,24 @@ fn try_open_project_append_os_lock(path: &Path, error_label: &str) -> Result { crate::runner::validate_windows_regular_file_handle(&file, error_label)?; if !existed { + // 自建对象的本地收紧不会触发 UAC(既有口径:本进程新建的 Windows 私有对象 + // 不因继承 DACL 自动提权),所以它留在持锁期间;**提权修复**不留在这里。 if let Err(error) = harden_new_game_creator_private_path(path, false, error_label) { drop(file); let _ = fs::remove_file(path); return Err(error); } } - crate::secure_windows_game_creator_path_for_current_user_with_auto_elevation( - path, false, true, - )?; + // 严格校验留在持锁期间(对象就是刚打开的这个句柄),**修复移到锁外**:提权修复会 + // `powershell.exe -Command "Start-Process -Verb RunAs -Wait …"` 同步等用户点 UAC + // (config.rs 的 attempt_elevated_windows_acl_repair),在这里等它等于把"用户犹豫 + // 的时间"记进别人的持锁窗口——1s 预算必然打满,而且只有 Windows 有这条路径。 + if let Err(error) = + crate::secure_windows_game_creator_path_for_current_user(path, false, true) + { + release_project_append_os_lock_then_repair_acl(file, path, &error)?; + return Ok(None); + } crate::runner::validate_windows_regular_file_handle(&file, error_label)?; Ok(Some(file)) }