BigPizzaV3/CodexPlusPlus · error

启动安装包失败:

Error message

启动安装包失败:{error}

What it means

On Windows, launch_installer spawns the downloaded installer with std::process::Command::new(path) plus CREATE_NO_WINDOW. If the OS fails to spawn the process, the error is mapped to 启动安装包失败:{error} with the raw io::Error text embedded. Common io errors: file not found, access denied, or the file is not a valid executable.

Solutions

  1. Read the embedded io error: NotFound → file missing; AccessDenied → AV/permissions; invalid exe → corrupt download.
  2. Verify the installer file exists at the UpdateInstall/installer_path and re-download if missing.
  3. Add the installer/URL to antivirus exclusions or whitelist the app if AV is blocking spawn.
  4. Re-run perform_update to get a fresh, complete download (a corrupt/truncated file will also fail to spawn).
  5. Launch the installer manually by double-clicking the downloaded file to isolate launcher vs installer problems.

Example fix

// before
let install = perform_update(&release, &dir).await?;
// after
match perform_update(&release, &dir).await {
    Ok(i) if i.launched => println!("installer started: {}", i.installer_path.display()),
    Ok(i) => println!("downloaded, run manually: {}", i.installer_path.display()),
    Err(e) if e.to_string().contains("启动安装包失败") => {
        eprintln!("spawn failed: {e}; run {} manually", expected_path.display());
    }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

fn installer_launchable(path: &std::path::Path) -> bool {
    path.is_file() && std::fs::metadata(path).map_or(false, |m| m.len() > 0)
}

Try / catch

match perform_update(&release, &dir).await {
    Ok(install) if install.launched => Ok(install),
    Ok(install) => {
        // launched == false on unsupported platforms; on Windows treat as manual install
        open_in_explorer(&install.installer_path); Ok(install)
    }
    Err(e) if e.to_string().contains("启动安装包失败") => {
        eprintln!("spawn failed: {e}; instruct user to run the installer manually");
        Err(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling perform_update on Windows when: the installer file was deleted/moved between download and launch; antivirus quarantined or blocked execution of the freshly downloaded .exe; the path contains characters the launcher mishandles; the downloaded file is corrupt or not a PE executable; insufficient permissions in the target directory.

Common situations: Windows Defender / SmartScreen marking the unsigned installer and blocking spawn; MSI vs NSIS mismatch causing 'not a valid Win32 application'; download truncated so the exe is corrupt; running from a temp dir cleaned concurrently.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/bfd51d570a2c23a3. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/update.rs:418

            || name.ends_with("setup.exe")
            || name.ends_with("installer.exe"))
}

fn is_macos_installer_asset(name: &str) -> bool {
    // Loose shape check; arch preference is handled by platform_asset_rank
    // via is_macos_native_arch_asset.
    name.contains("codex") && name.contains("plus") && name.ends_with(".dmg")
}

pub fn launch_installer(path: &Path) -> anyhow::Result<()> {
    #[cfg(windows)]
    {
        use std::os::windows::process::CommandExt;
        std::process::Command::new(path)
            .creation_flags(crate::windows_integration::CREATE_NO_WINDOW)
            .spawn()
            .map(|_| ())
            .map_err(|error| anyhow::anyhow!("启动安装包失败:{error}"))
    }

    #[cfg(target_os = "macos")]
    {
        std::process::Command::new("open")
            .arg(path)
            .spawn()
            .map(|_| ())
            .map_err(|error| anyhow::anyhow!("打开 DMG 失败:{error}"))
    }

    #[cfg(all(not(windows), not(target_os = "macos")))]
    {
        let _ = path;
        anyhow::bail!("当前平台不支持启动安装包")
    }
}

View on GitHub (pinned to b1ed92e5e4)