{"record":{"id":"bfd51d570a2c23a3","repo":"BigPizzaV3/CodexPlusPlus","slug":"error-bfd51d","errorCode":null,"errorMessage":"启动安装包失败：{error}","messagePattern":"启动安装包失败：(.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/update.rs","lineNumber":418,"sourceCode":"            || name.ends_with(\"setup.exe\")\n            || name.ends_with(\"installer.exe\"))\n}\n\nfn is_macos_installer_asset(name: &str) -> bool {\n    // Loose shape check; arch preference is handled by platform_asset_rank\n    // via is_macos_native_arch_asset.\n    name.contains(\"codex\") && name.contains(\"plus\") && name.ends_with(\".dmg\")\n}\n\npub fn launch_installer(path: &Path) -> anyhow::Result<()> {\n    #[cfg(windows)]\n    {\n        use std::os::windows::process::CommandExt;\n        std::process::Command::new(path)\n            .creation_flags(crate::windows_integration::CREATE_NO_WINDOW)\n            .spawn()\n            .map(|_| ())\n            .map_err(|error| anyhow::anyhow!(\"启动安装包失败：{error}\"))\n    }\n\n    #[cfg(target_os = \"macos\")]\n    {\n        std::process::Command::new(\"open\")\n            .arg(path)\n            .spawn()\n            .map(|_| ())\n            .map_err(|error| anyhow::anyhow!(\"打开 DMG 失败：{error}\"))\n    }\n\n    #[cfg(all(not(windows), not(target_os = \"macos\")))]\n    {\n        let _ = path;\n        anyhow::bail!(\"当前平台不支持启动安装包\")\n    }\n}\n","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/1f431ae49b57b3055e0e6845ba6156c6b4232b4d/crates/codex-plus-core/src/update.rs#L400-L436","documentation":"On Windows, launch_installer spawns the downloaded installer with std::process::Command::new(path) (using CREATE_NO_WINDOW). If the OS refuses to spawn — file missing, not an executable, permission denied, AV interference — the io::Error is wrapped as \"启动安装包失败：{error}\". This is spawn failure (the process never started), not a non-zero installer exit code, which launch_installer does not check at all.","triggerScenarios":"The installer file was deleted between perform_update finishing and launch_installer being called (temp-dir cleanup); the downloaded asset was not actually a .exe (wrong platform asset selected); antivirus/SmartScreen quarantined the binary; the path is on a blocked or UNC location.","commonSituations":"Apps downloading to a temp dir the OS cleans aggressively; managed devices where AV auto-quarantines unsigned installers; races with cleanup code running right after the update completes.","solutions":["Verify the path exists and has the expected .exe extension immediately before launching","Re-run perform_update to re-download, then launch without delay","Check antivirus/quarantine history; add an exclusion or code-sign the installer","Keep the download directory alive until the installer has been spawned"],"exampleFix":"// before\nlaunch_installer(&install.installer_path)?;\n\n// after\nlet path = &install.installer_path;\nif !path.is_file() {\n    anyhow::bail!(\"installer missing before launch: {}\", path.display());\n}\nlaunch_installer(path)?;","handlingStrategy":"try-catch","validationCode":"let path = &install.installer_path;\nif !path.is_file() || path.extension().is_none_or(|e| e != \"exe\") {\n    anyhow::bail!(\"installer missing or not an exe before launch: {}\", path.display());\n}\nlaunch_installer(path)?;","typeGuard":null,"tryCatchPattern":"match launch_installer(&install.installer_path) {\n    Ok(()) => { /* spawned */ }\n    Err(err) if err.to_string().contains(\"启动安装包失败\") => {\n        // re-download via perform_update and retry the launch once; check AV quarantine if it persists\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Keep the download directory alive until the installer has actually spawned","Code-sign installers and document AV exclusions to avoid quarantine of the downloaded binary","Verify existence and extension right before spawning"],"tags":["windows","installer","process-spawn","update"],"backgroundTag":"installer-launch-failed","analyzedSha":"1f431ae49b57b3055e0e6845ba6156c6b4232b4d","analyzedAt":"2026-08-16T20:54:18.598Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}