Files
Starlight_Lancher/apps/app/src/portable.rs

75 lines
2.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::sync::atomic::{AtomicBool, Ordering};
const PORTABLE_DIR_NAME: &str = ".Axolotl";
static PORTABLE_MODE: AtomicBool = AtomicBool::new(false);
/// 在启动时初始化便携模式
/// 检查 `.Axolotl` 文件夹是否存在且可写
/// 如果存在且可写,将 `THESEUS_CONFIG_DIR` 环境变量设置为该路径
/// 返回 `true` 如果便携模式已启用,否则返回 `false`
///
/// 必须在 main() 开头、任何其他线程(包括 tokio runtime启动之前调用。
/// 此函数内部会调用 `std::env::set_var`,该函数在 Rust 中不是线程安全的。
pub unsafe fn init_portable_mode() -> bool {
let exe_path = match std::env::current_exe() {
Ok(p) => p,
Err(_) => return false,
};
let Some(app_dir) = exe_path.parent() else {
return false;
};
let portable_dir = app_dir.join(PORTABLE_DIR_NAME);
if !portable_dir.is_dir() {
return false;
}
if !try_write_test(&portable_dir) {
return false;
}
// SAFETY: 调用者保证此时没有其他线程访问环境变量
unsafe {
std::env::set_var("THESEUS_CONFIG_DIR", &portable_dir);
}
PORTABLE_MODE.store(true, Ordering::Relaxed);
tracing::info!(
"Portable mode enabled: THESEUS_CONFIG_DIR={}",
portable_dir.display()
);
true
}
/// 尝试在目标目录中创建并删除临时文件以验证可写性。
/// 先删除可能残留的 `.write_test`,避免已有的只读文件导致 `File::create` 失败。
fn try_write_test(dir: &std::path::Path) -> bool {
let test_file = dir.join(".write_test");
let _ = std::fs::remove_file(&test_file);
match std::fs::File::create(&test_file) {
Ok(_) => {
let _ = std::fs::remove_file(&test_file);
true
}
Err(e) => {
tracing::warn!(
"Portable directory {} exists but is not writable: {}",
dir.display(),
e
);
false
}
}
}
/// Tauri 命令:检查应用程序是否运行在便携模式下
#[tauri::command]
pub fn is_portable_mode() -> bool {
PORTABLE_MODE.load(Ordering::Relaxed)
}