问题
应用没有单实例防护。src-tauri/src/lib.rs 的 Tauri builder 只注册了 updater / process / dialog / autostart,没有 tauri-plugin-single-instance,代码里也没有自实现的实例锁。
影响
本应用会下载、替换 Codex.app(inside-out 签名替换)、MSIX sideload、卸载——都是改文件系统的操作。两个实例并发执行 → 同一临时路径冲突、替换到一半的损坏、状态互相覆盖。
平台差异:
- macOS:LaunchServices 让常规启动(Dock /
open)默认激活已有实例,日常较难多开(但 open -n / 直接 exec 二进制可绕过)。
- Windows:无 OS 级保护,双击 exe 两次 = 两个独立进程,portable 版尤其容易。这是主要暴露面。
建议
接入官方 tauri-plugin-single-instance(跨平台):第二个实例启动即退出,把焦点交还给第一个实例,并 unminimize(与最小化按钮协同):
// 官方建议第一个注册
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
if let Some(w) = app.get_webview_window("main") {
let _ = w.unminimize();
let _ = w.show();
let _ = w.set_focus();
}
}))
优先级:P1(Windows 易触发 + 后果严重)。
问题
应用没有单实例防护。
src-tauri/src/lib.rs的 Tauri builder 只注册了 updater / process / dialog / autostart,没有tauri-plugin-single-instance,代码里也没有自实现的实例锁。影响
本应用会下载、替换 Codex.app(inside-out 签名替换)、MSIX sideload、卸载——都是改文件系统的操作。两个实例并发执行 → 同一临时路径冲突、替换到一半的损坏、状态互相覆盖。
平台差异:
open)默认激活已有实例,日常较难多开(但open -n/ 直接 exec 二进制可绕过)。建议
接入官方
tauri-plugin-single-instance(跨平台):第二个实例启动即退出,把焦点交还给第一个实例,并 unminimize(与最小化按钮协同):优先级:P1(Windows 易触发 + 后果严重)。