From e7b985c23369375064929cb4be47d860293d03c9 Mon Sep 17 00:00:00 2001 From: lbl <1791778603@qq.com> Date: Fri, 21 Aug 2026 02:47:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(utils):=20fallback=20=E8=AE=BE=E5=A4=87=20I?= =?UTF-8?q?D=20=E6=96=87=E4=BB=B6=E9=94=9A=E5=AE=9A=E5=8F=AF=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit machine_uid 获取失败时的 fallback 使用相对路径 "device_id", 读写位置随进程 CWD 变化,换个目录启动就会生成新 UUID, 设备 ID 漂移。 改为锚定 current_exe 所在目录(取不到时退回原相对路径行为)。 测试:test_fallback_id_path_is_absolute 验证路径为绝对路径。 --- vnt-core/src/utils/device_id.rs | 34 ++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/vnt-core/src/utils/device_id.rs b/vnt-core/src/utils/device_id.rs index 15a337c..6d9e7fb 100644 --- a/vnt-core/src/utils/device_id.rs +++ b/vnt-core/src/utils/device_id.rs @@ -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 { match machine_uid::get() { Ok(id) => return Ok(id), @@ -11,10 +11,21 @@ pub fn get_device_id() -> anyhow::Result { get_fallback_id() } -fn get_fallback_id() -> anyhow::Result { - 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 { + 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 { 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"); + } +}