fix: 修复硬件采集过滤虚拟GPU驱动
- GPU采集过滤IddDriver/Virtual等虚拟显示驱动,优先返回真实显卡 - 磁盘采集仅选择HDD/SSD类型,排除可移动设备 - 提取powershell_lines辅助函数支持多行输出
This commit is contained in:
@@ -53,11 +53,13 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result<HardwareAsset> {
|
|||||||
// Disk — pick the largest non-removable disk
|
// Disk — pick the largest non-removable disk
|
||||||
let disks = sysinfo::Disks::new_with_refreshed_list();
|
let disks = sysinfo::Disks::new_with_refreshed_list();
|
||||||
let (disk_model, disk_total_mb) = disks.iter()
|
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())
|
.max_by_key(|d| d.total_space())
|
||||||
.map(|d| {
|
.map(|d| {
|
||||||
let name = d.name().to_string_lossy().to_string();
|
|
||||||
let total = d.total_space() / 1024 / 1024;
|
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));
|
.unwrap_or_else(|| ("Unknown".to_string(), 0));
|
||||||
|
|
||||||
@@ -79,7 +81,14 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result<HardwareAsset> {
|
|||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
fn collect_system_details() -> (Option<String>, Option<String>, Option<String>) {
|
fn collect_system_details() -> (Option<String>, Option<String>, Option<String>) {
|
||||||
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_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 mb_product = powershell_first("Get-CimInstance Win32_BaseBoard | Select-Object -ExpandProperty Product");
|
||||||
let motherboard = match (mb_manufacturer, mb_product) {
|
let motherboard = match (mb_manufacturer, mb_product) {
|
||||||
@@ -98,19 +107,29 @@ fn collect_system_details() -> (Option<String>, Option<String>, Option<String>)
|
|||||||
(None, None, None)
|
(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")]
|
#[cfg(target_os = "windows")]
|
||||||
fn powershell_first(command: &str) -> Option<String> {
|
fn powershell_lines(command: &str) -> Vec<String> {
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
let output = Command::new("powershell")
|
let output = match Command::new("powershell")
|
||||||
.args(["-NoProfile", "-NonInteractive", "-Command",
|
.args(["-NoProfile", "-NonInteractive", "-Command",
|
||||||
&format!("[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; {}", command)])
|
&format!("[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; {}", command)])
|
||||||
.output()
|
.output()
|
||||||
.ok()?;
|
{
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
Ok(o) => o,
|
||||||
stdout.lines()
|
Err(_) => return Vec::new(),
|
||||||
|
};
|
||||||
|
String::from_utf8_lossy(&output.stdout)
|
||||||
|
.lines()
|
||||||
.map(|l| l.trim().to_string())
|
.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<String> {
|
||||||
|
powershell_lines(command).into_iter().next()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collect installed software from Windows Registry via PowerShell.
|
/// Collect installed software from Windows Registry via PowerShell.
|
||||||
|
|||||||
Reference in New Issue
Block a user