Skip to content

[Windows] 全新安装后双击 exe 无反应:migrate_config_if_needed 在配置文件不存在时强制备份导致 os error 2 崩溃 #18

Description

@Nightchamp

描述 / Description

Windows x64 全新安装 v0.1.15(linuxdo-accelerator_0.1.15_x64-setup.exe)后,
双击 linuxdo-accelerator.exe 没有任何反应:没有窗口、没有托盘图标、也没有报错弹窗,
进程启动后立即退出。

环境 / Environment

  • OS: Windows 10/11 x64
  • 版本: v0.1.15(最新 release)
  • 安装方式: 官方 x64-setup.exe,默认路径 C:\Program Files\Linux.do Accelerator

复现步骤 / Steps to Reproduce

  1. 全新安装 v0.1.15(或删除 %APPDATA%\linuxdo\linuxdo-accelerator\config\ 下所有文件)
  2. 双击 linuxdo-accelerator.exe
  3. 没有任何界面出现

从命令行运行时可以看到真实报错:


$ linuxdo-accelerator.exe
Error: failed to back up C:\Users<user>\AppData\Roaming\linuxdo\linuxdo-accelerator\config\linuxdo-accelerator.toml
       to C:\Users<user>\AppData\Roaming\linuxdo\linuxdo-accelerator\config\linuxdo-accelerator.toml.bak

Caused by:
    系统找不到指定的文件。 (os error 2)

根因分析 / Root Cause

问题出在 src/config.rsAppConfig::migrate_config_if_needed()(main 分支约 170-194 行):

pub fn migrate_config_if_needed(path: &Path) -> Result<bool> {
    if let Some(parent) = path.parent() {
        fs::create_dir_all(parent) /* ... */ ?;
    }

    let marker_path = version_marker_path(path);
    if path.exists() && marker_matches_current_version(&marker_path) {
        return Ok(false);
    }

    let backup_path = backup_config_path(path);
    fs::copy(path, &backup_path) /* ... */ ?;   // <-- BUG
    // ...
}

当配置目录存在但 linuxdo-accelerator.toml 不存在时(全新安装就是这种情况),
fs::copy 会因源文件缺失直接返回 os error 2,错误沿 ? 一路向上传播,
导致程序在 GUI 初始化前就退出。由于 exe 是 windows_subsystem = "windows",
错误不会弹窗,表现为"双击没反应"。

src/service.rs 的 init_config()(38-41 行)在 load_or_create() 之前调用
migrate_config_if_needed(),而 load_or_create() 里其实已正确处理了
!path.exists() 的分支,但永远走不到。

临时解决方法 / Workaround

先执行一次隐藏命令 config-json(它直接调用 load_or_create(),会正确创建配置和版本标记):

  "C:\Program Files\Linux.do Accelerator\linuxdo-accelerator.exe" config-json

之后双击即可正常启动。已在本机验证。

建议修复 / Suggested Fix

在 migrate_config_if_needed() 中,仅当配置文件存在时才做备份:

  let backup_path = backup_config_path(path);
  if path.exists() {
      fs::copy(path, &backup_path).with_context(|| {
          format!("failed to back up {} to {}", path.display(), backup_path.display())
      })?;
  }

或更直接:文件不存在时直接跳过迁移:

  if !path.exists() {
      return Ok(false); // load_or_create() 会负责创建默认配置
  }

影响范围 / Impact

所有首次安装、或配置目录被清空过的用户都会触发;已配置好(有 toml + version 标记)的
老用户不受影响。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions