fix(utils): fallback 设备 ID 文件锚定可执行文件目录

machine_uid 获取失败时的 fallback 使用相对路径 "device_id",
读写位置随进程 CWD 变化,换个目录启动就会生成新 UUID,
设备 ID 漂移。

改为锚定 current_exe 所在目录(取不到时退回原相对路径行为)。

测试:test_fallback_id_path_is_absolute 验证路径为绝对路径。
This commit is contained in:
lbl
2026-08-21 02:47:53 +08:00
parent cc80bd2d37
commit e7b985c233
+29 -5
View File
@@ -1,6 +1,6 @@
use anyhow::Context;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
pub fn get_device_id() -> anyhow::Result<String> {
match machine_uid::get() {
Ok(id) => return Ok(id),
@@ -11,10 +11,21 @@ pub fn get_device_id() -> anyhow::Result<String> {
get_fallback_id()
}
fn get_fallback_id() -> anyhow::Result<String> {
let path = Path::new("device_id");
if let Ok(content) = fs::read_to_string(path) {
/// fallback 设备 ID 文件路径:锚定可执行文件所在目录。
/// 相对路径会随进程 CWD 变化,换目录启动就会读写另一个文件,
/// 导致设备 ID 漂移
fn fallback_id_path() -> PathBuf {
std::env::current_exe()
.ok()
.and_then(|p| p.parent().map(|dir| dir.join("device_id")))
.unwrap_or_else(|| PathBuf::from("device_id"))
}
fn get_fallback_id() -> anyhow::Result<String> {
let path = fallback_id_path();
if let Ok(content) = fs::read_to_string(&path) {
let id = content.trim();
if !id.is_empty() {
return Ok(id.to_string());
@@ -23,7 +34,20 @@ fn get_fallback_id() -> anyhow::Result<String> {
let new_id = uuid::Uuid::new_v4().to_string();
fs::write(path, &new_id).context("Failed to write device_id file")?;
fs::write(&path, &new_id).context("Failed to write device_id file")?;
Ok(new_id)
}
#[cfg(test)]
mod tests {
use super::*;
/// 路径必须锚定到可执行文件目录(绝对路径),不能是随 CWD 漂移的相对路径
#[test]
fn test_fallback_id_path_is_absolute() {
let path = fallback_id_path();
assert!(path.is_absolute(), "path should be absolute: {path:?}");
assert_eq!(path.file_name().unwrap(), "device_id");
}
}