use std::error::Error;
use std::os::windows::process::CommandExt;
use std::process::Command;
const CREATE_NO_WINDOW: u32 = 0x08000000;
fn try_wmic(args: &[&str]) -> Option<String> {
let output = Command::new("wmic")
.args(args)
.creation_flags(CREATE_NO_WINDOW)
.output()
.ok()?;
let text = String::from_utf8_lossy(&output.stdout);
let value = text.lines().nth(1).unwrap_or("").trim().to_string();
if value.is_empty() {
None
} else {
Some(value)
}
}
fn try_wmic_list(class: &str, key: &str) -> Option<String> {
let output = Command::new("wmic")
.args([class, "get", "/format:list"])
.creation_flags(CREATE_NO_WINDOW)
.output()
.ok()?;
let text = String::from_utf8_lossy(&output.stdout);
for line in text.lines() {
if line.starts_with(&format!("{}=", key)) {
let parts: Vec<&str> = line.split('=').collect();
if parts.len() == 2 {
let value = parts[1].trim().to_string();
if !value.is_empty() {
return Some(value);
}
}
}
}
None
}
pub fn get_cpu_id() -> Result<String, Box<dyn Error>> {
if let Some(val) = try_wmic(&["cpu", "get", "ProcessorId"]) {
return Ok(val);
}
if let Some(val) = try_wmic_list("cpu", "ProcessorId") {
return Ok(val);
}
Ok("windows_cpu_unknown".to_string())
}
pub fn get_motherboard_id() -> Result<String, Box<dyn Error>> {
if let Some(val) = try_wmic(&["baseboard", "get", "SerialNumber"]) {
return Ok(val);
}
if let Some(val) = try_wmic_list("baseboard", "SerialNumber") {
return Ok(val);
}
Ok("windows_mb_unknown".to_string())
}