br_system/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#[cfg(target_os = "macos")]
mod mac;
#[cfg(target_os = "windows")]
mod win;
#[derive(Debug, Clone)]
pub struct SystemInfo {
    /// CPU核心数量
    pub cores: usize,
    /// 内存容量
    pub memory: String,
    /// 硬盘的序列号
    pub serial_number: Vec<String>,
    /// 硬件uuid
    pub hardware_uuid: String,
    /// 设备UUID
    pub uuid: String,
}

impl SystemInfo {
    pub fn new() -> Result<Self, String> {
        let mut that = Self {
            cores: 0,
            memory: "".to_string(),
            serial_number: vec![],
            hardware_uuid: "".to_string(),
            uuid: "".to_string(),
        };
        if cfg!(target_os = "macos") {
            #[cfg(target_os = "macos")]
            {
                return that.mac_os();
            }
        }
        if cfg!(target_os = "windows") {
            #[cfg(target_os = "windows")]
            {
                return that.windows();
            }
        }
        Ok(that)
    }
    #[cfg(target_os = "macos")]
    pub fn mac_os(&mut self) -> Result<Self, String> {
        self.uuid = mac::get_uuid().unwrap_or("".to_string());
        self.serial_number = vec![self.uuid.clone()];
        Ok(self.clone())
    }

    #[cfg(target_os = "windows")]
    pub fn windows(&mut self) -> Result<&mut Self, String> {
        // self.uuid = win::get_uuid().unwrap_or("".to_string());
        // self.serial_number = vec![self.uuid.clone()];
        // return Ok(self);

        // 硬盘序列号
        let disk_output = match Command::new("wmic")
            .args(&["diskdrive", "get", "SerialNumber"])
            .output() {
            Ok(e) => e,
            Err(e) => {
                return Err(format!("{}", e.to_string()));
            }
        };
        let serial_number = String::from_utf8_lossy(&disk_output.stdout);
        for line in serial_number.lines() {
            let text = line.trim();
            if !text.contains("SerialNumber") && !text.is_empty() {
                self.serial_number.push(text.to_string())
            }
        }

        // cpu信息
        let cpu_output = match Command::new("wmic")
            .args(&["cpu", "get", "NumberOfCores"])
            .output() {
            Ok(e) => e,
            Err(e) => {
                return Err(format!("Failed to get CPU info: {}", e.to_string()));
            }
        };
        let cpu_info = String::from_utf8_lossy(&cpu_output.stdout);
        for line in cpu_info.lines() {
            let text = line.trim();
            if text.chars().all(|c| c.is_digit(10)) && !text.is_empty() {
                // 找到就退出
                self.cores = text.parse::<usize>().unwrap();
                break;
            }
        }

        // 内存信息
        let memory_output = match Command::new("wmic")
            .args(&["memorychip", "get", "capacity"])
            .output() {
            Ok(e) => e,
            Err(e) => {
                return Err(format!("Failed to get memory info: {}", e.to_string()));
            }
        };
        let memory_info = String::from_utf8_lossy(&memory_output.stdout);
        let mut total_memory: u64 = 0;
        for line in memory_info.lines() {
            let text = line.trim();
            if text.chars().all(|c| c.is_digit(10)) && !text.is_empty() {
                if let Ok(capacity) = text.parse::<u64>() {
                    // 将每个内存条的容量累加以获得总的物理内存量(以字节为单位)
                    total_memory += capacity;
                }
            }
        }
        // 除以 1024 的三次方 将字节转换为 GB,并存储在结构体中
        self.memory = format!("{} GB", total_memory / 1024u64.pow(3));

        // 解析硬盘 UUID
        let uuid_output = match Command::new("powershell")
            .args(&["Get-WmiObject", "Win32_DiskDrive", "|", "Select-Object", "-ExpandProperty", "Signature"])
            .output() {
            Ok(e) => e,
            Err(e) => {
                return Err(format!("Failed to get disk UUIDs: {}", e.to_string()));
            }
        };
        let uuid = String::from_utf8_lossy(&uuid_output.stdout);
        for line in uuid.lines() {
            let text = line.trim();
            if !text.is_empty() {
                self.hardware_uuid = text.to_string();
                break;
            }
        }

        Ok(self)
    }
}