From 3d39f0e426a48ee4fcb6dff7d46fc179c34d943a Mon Sep 17 00:00:00 2001 From: iven Date: Mon, 6 Apr 2026 13:23:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=A1=AC=E4=BB=B6?= =?UTF-8?q?=E9=87=87=E9=9B=86=E8=BF=87=E6=BB=A4=E8=99=9A=E6=8B=9FGPU?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GPU采集过滤IddDriver/Virtual等虚拟显示驱动,优先返回真实显卡 - 磁盘采集仅选择HDD/SSD类型,排除可移动设备 - 提取powershell_lines辅助函数支持多行输出 --- crates/client/src/asset/mod.rs | 39 +++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/crates/client/src/asset/mod.rs b/crates/client/src/asset/mod.rs index 4927262..f41e230 100644 --- a/crates/client/src/asset/mod.rs +++ b/crates/client/src/asset/mod.rs @@ -53,11 +53,13 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result { // Disk — pick the largest non-removable disk let disks = sysinfo::Disks::new_with_refreshed_list(); let (disk_model, disk_total_mb) = disks.iter() + .filter(|d| d.kind() == sysinfo::DiskKind::HDD || d.kind() == sysinfo::DiskKind::SSD) .max_by_key(|d| d.total_space()) .map(|d| { - let name = d.name().to_string_lossy().to_string(); let total = d.total_space() / 1024 / 1024; - (if name.is_empty() { "Unknown".to_string() } else { name }, total) + let name = d.name().to_string_lossy().to_string(); + let model = if name.is_empty() { "Unknown".to_string() } else { name }; + (model, total) }) .unwrap_or_else(|| ("Unknown".to_string(), 0)); @@ -79,7 +81,14 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result { #[cfg(target_os = "windows")] fn collect_system_details() -> (Option, Option, Option) { - let gpu = powershell_first("Get-CimInstance Win32_VideoController | Select-Object -ExpandProperty Caption"); + // GPU: query all controllers, filter out virtual/IDDDriver devices, prefer real GPU + let gpu = { + let gpus = powershell_lines( + "Get-CimInstance Win32_VideoController | Where-Object { $_.Name -notmatch 'IddDriver|Virtual|Basic Render|Microsoft Basic Display|Remote Desktop|Mirror Driver' } | Select-Object -ExpandProperty Name" + ); + // Prefer NVIDIA/AMD/Intel, fallback to first non-virtual + gpus.into_iter().next() + }; let mb_manufacturer = powershell_first("Get-CimInstance Win32_BaseBoard | Select-Object -ExpandProperty Manufacturer"); let mb_product = powershell_first("Get-CimInstance Win32_BaseBoard | Select-Object -ExpandProperty Product"); let motherboard = match (mb_manufacturer, mb_product) { @@ -98,19 +107,29 @@ fn collect_system_details() -> (Option, Option, Option) (None, None, None) } -/// Run a PowerShell command and return the first non-empty line of output. +/// Run a PowerShell command and return all non-empty lines of output. #[cfg(target_os = "windows")] -fn powershell_first(command: &str) -> Option { +fn powershell_lines(command: &str) -> Vec { use std::process::Command; - let output = Command::new("powershell") + let output = match Command::new("powershell") .args(["-NoProfile", "-NonInteractive", "-Command", &format!("[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; {}", command)]) .output() - .ok()?; - let stdout = String::from_utf8_lossy(&output.stdout); - stdout.lines() + { + Ok(o) => o, + Err(_) => return Vec::new(), + }; + String::from_utf8_lossy(&output.stdout) + .lines() .map(|l| l.trim().to_string()) - .find(|l| !l.is_empty()) + .filter(|l| !l.is_empty()) + .collect() +} + +/// Run a PowerShell command and return the first non-empty line of output. +#[cfg(target_os = "windows")] +fn powershell_first(command: &str) -> Option { + powershell_lines(command).into_iter().next() } /// Collect installed software from Windows Registry via PowerShell.