[feat] more hw info including gpu + refactor fpstest

This commit is contained in:
2025-11-08 15:43:44 +08:00
parent e146fbe393
commit e824455577
25 changed files with 2560 additions and 977 deletions

215
src-tauri/Cargo.lock generated
View File

@@ -10,6 +10,7 @@ dependencies = [
"base64 0.22.1",
"dirs 6.0.0",
"futures-util",
"gfxinfo",
"log",
"notify",
"regex",
@@ -880,14 +881,38 @@ dependencies = [
"syn 2.0.108",
]
[[package]]
name = "darling"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
"darling_core 0.20.11",
"darling_macro 0.20.11",
]
[[package]]
name = "darling"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
dependencies = [
"darling_core",
"darling_macro",
"darling_core 0.21.3",
"darling_macro 0.21.3",
]
[[package]]
name = "darling_core"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.108",
]
[[package]]
@@ -904,13 +929,24 @@ dependencies = [
"syn 2.0.108",
]
[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core 0.20.11",
"quote",
"syn 2.0.108",
]
[[package]]
name = "darling_macro"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [
"darling_core",
"darling_core 0.21.3",
"quote",
"syn 2.0.108",
]
@@ -1657,6 +1693,21 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gfxinfo"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f33b12fba19d158bebe0262fd2b6c49fee6f0e0e089f4f3fdc11c017548473"
dependencies = [
"core-foundation 0.10.1",
"io-kit-sys",
"libdrm_amdgpu_sys",
"nvml-wrapper",
"serde",
"windows 0.61.3",
"wmi",
]
[[package]]
name = "gio"
version = "0.18.4"
@@ -2236,6 +2287,16 @@ dependencies = [
"libc",
]
[[package]]
name = "io-kit-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b"
dependencies = [
"core-foundation-sys",
"mach2",
]
[[package]]
name = "ipnet"
version = "2.11.0"
@@ -2454,6 +2515,15 @@ version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "libdrm_amdgpu_sys"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a7bf95f3c5d8a8ae4a5c0c46fe2271c16fdf8fd4b26978f44b082a0f8ebaaae"
dependencies = [
"libc",
]
[[package]]
name = "libloading"
version = "0.7.4"
@@ -2845,6 +2915,29 @@ dependencies = [
"syn 2.0.108",
]
[[package]]
name = "nvml-wrapper"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c9bff0aa1d48904a1385ea2a8b97576fbdcbc9a3cfccd0d31fe978e1c4038c5"
dependencies = [
"bitflags 2.10.0",
"libloading 0.8.9",
"nvml-wrapper-sys",
"static_assertions",
"thiserror 1.0.69",
"wrapcenum-derive",
]
[[package]]
name = "nvml-wrapper-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "698d45156f28781a4e79652b6ebe2eaa0589057d588d3aec1333f6466f13fcb5"
dependencies = [
"libloading 0.8.9",
]
[[package]]
name = "objc-sys"
version = "0.3.5"
@@ -4401,7 +4494,7 @@ version = "3.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955"
dependencies = [
"darling",
"darling 0.21.3",
"proc-macro2",
"quote",
"syn 2.0.108",
@@ -6254,7 +6347,7 @@ dependencies = [
"webview2-com-sys",
"windows 0.61.3",
"windows-core 0.61.2",
"windows-implement",
"windows-implement 0.60.2",
"windows-interface",
]
@@ -6342,17 +6435,39 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
dependencies = [
"windows-collections 0.1.1",
"windows-core 0.60.1",
"windows-future 0.1.1",
"windows-link 0.1.3",
"windows-numerics 0.1.1",
]
[[package]]
name = "windows"
version = "0.61.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
dependencies = [
"windows-collections",
"windows-collections 0.2.0",
"windows-core 0.61.2",
"windows-future",
"windows-future 0.2.1",
"windows-link 0.1.3",
"windows-numerics",
"windows-numerics 0.2.0",
]
[[package]]
name = "windows-collections"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec"
dependencies = [
"windows-core 0.60.1",
]
[[package]]
@@ -6373,13 +6488,26 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
dependencies = [
"windows-implement 0.59.0",
"windows-interface",
"windows-link 0.1.3",
"windows-result 0.3.4",
"windows-strings 0.3.1",
]
[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-implement 0.60.2",
"windows-interface",
"windows-link 0.1.3",
"windows-result 0.3.4",
@@ -6392,13 +6520,23 @@ version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-implement 0.60.2",
"windows-interface",
"windows-link 0.2.1",
"windows-result 0.4.1",
"windows-strings 0.5.1",
]
[[package]]
name = "windows-future"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0"
dependencies = [
"windows-core 0.60.1",
"windows-link 0.1.3",
]
[[package]]
name = "windows-future"
version = "0.2.1"
@@ -6410,6 +6548,17 @@ dependencies = [
"windows-threading",
]
[[package]]
name = "windows-implement"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
@@ -6444,6 +6593,16 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-numerics"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed"
dependencies = [
"windows-core 0.60.1",
"windows-link 0.1.3",
]
[[package]]
name = "windows-numerics"
version = "0.2.0"
@@ -6483,6 +6642,15 @@ dependencies = [
"windows-link 0.2.1",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link 0.1.3",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
@@ -6812,6 +6980,33 @@ dependencies = [
"wayland-protocols-wlr",
]
[[package]]
name = "wmi"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f902b4592b911109e7352bcfec7b754b07ec71e514d7dfa280eaef924c1cb08"
dependencies = [
"chrono",
"futures",
"log",
"serde",
"thiserror 2.0.17",
"windows 0.60.0",
"windows-core 0.60.1",
]
[[package]]
name = "wrapcenum-derive"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e"
dependencies = [
"darling 0.20.11",
"proc-macro2",
"quote",
"syn 2.0.108",
]
[[package]]
name = "writeable"
version = "0.6.2"

View File

@@ -55,6 +55,7 @@ anyhow = "1.0.100"
notify = "8.2.0"
dirs = "6.0.0"
tokio = { version = "1.40", features = ["process"] }
gfxinfo = "0.1.2"
[target.'cfg(windows)'.dependencies] # Windows Only
winreg = "0.55.0"

View File

@@ -11,6 +11,7 @@ use std::path::Path;
use std::io::{BufRead, BufReader};
use tauri::path::BaseDirectory;
use tauri::Manager;
use serde::{Deserialize, Serialize};
// use tauri_plugin_shell::ShellExt;
@@ -368,9 +369,45 @@ pub async fn get_computer_info() -> Result<serde_json::Value, String> {
return Ok(serde_json::json!({}));
}
let json: serde_json::Value = serde_json::from_str(cleaned)
let mut json: serde_json::Value = serde_json::from_str(cleaned)
.map_err(|e| format!("解析 JSON 失败: {},原始输出: {}", e, cleaned))?;
// 对于 Windows 11优先使用 OSDisplayVersion 获取版本代码(如 25H2
// 如果 OSDisplayVersion 存在且包含版本代码,提取它
if let Some(os_display_version) = json.get("OSDisplayVersion").and_then(|v| v.as_str()) {
// OSDisplayVersion 格式可能是 "25H2" 或 "Windows 11 版本 25H2" 等
// 尝试提取版本代码(如 25H2
if let Some(capture) = regex::Regex::new(r"(\d+H\d+)")
.ok()
.and_then(|re| re.captures(os_display_version))
{
if let Some(version_code) = capture.get(1) {
json["ReleaseId"] = serde_json::Value::String(version_code.as_str().to_string());
}
}
}
// 如果没有从 OSDisplayVersion 获取到版本代码,尝试从注册表获取 ReleaseId
if !json.get("ReleaseId").and_then(|v| v.as_str()).is_some() {
let release_id_output = Command::new("powershell")
.args(&[
"-NoProfile",
"-Command",
"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; try { (Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion').ReleaseId } catch { $null }"
])
.output()
.await;
if let Ok(release_output) = release_id_output {
if release_output.status.success() {
let release_str = String::from_utf8_lossy(&release_output.stdout).trim().to_string();
if !release_str.is_empty() {
json["ReleaseId"] = serde_json::Value::String(release_str);
}
}
}
}
Ok(json)
}
@@ -379,4 +416,63 @@ pub async fn get_computer_info() -> Result<serde_json::Value, String> {
#[cfg(not(target_os = "windows"))]
pub async fn get_computer_info() -> Result<serde_json::Value, String> {
Ok(serde_json::json!({}))
}
/// GPU 信息结构体
#[derive(Debug, Serialize, Deserialize)]
pub struct GpuInfo {
vendor: String,
model: String,
family: String,
device_id: String,
total_vram: u64,
used_vram: u64,
load_pct: u32,
temperature: f64,
}
/// 辅助函数:格式化字节数
fn format_bytes(bytes: u64) -> String {
let gb = bytes as f64 / 1024.0 / 1024.0 / 1024.0;
if gb >= 1.0 {
format!("{:.2}GB", gb)
} else {
let mb = bytes as f64 / 1024.0 / 1024.0;
format!("{:.2}MB", mb)
}
}
/// 获取 GPU 信息
#[tauri::command]
pub fn get_gpu_info() -> Result<Option<GpuInfo>, String> {
use gfxinfo::active_gpu;
match active_gpu() {
Ok(gpu) => {
let info = gpu.info();
let temp = info.temperature() as f64 / 1000.0;
Ok(Some(GpuInfo {
vendor: gpu.vendor().to_string(),
model: gpu.model().to_string(),
family: gpu.family().to_string(),
device_id: gpu.device_id().to_string(),
total_vram: info.total_vram(),
used_vram: info.used_vram(),
load_pct: info.load_pct(),
temperature: temp,
}))
}
Err(e) => {
println!("✗ GPU 信息获取失败: {}", e);
Ok(None)
}
}
}
/// 获取显示器信息(非 Windows 平台返回空)
#[tauri::command]
#[cfg(not(target_os = "windows"))]
pub async fn get_monitor_info() -> Result<Vec<MonitorInfo>, String> {
Ok(vec![])
}

View File

@@ -170,6 +170,8 @@ fn main() {
cmds::download_app_update,
cmds::install_app_update,
cmds::get_computer_info,
cmds::get_gpu_info,
cmds::get_monitor_info,
on_button_clicked
])
.run(ctx)