发布时间:2026/8/29 20:32:47
【IT】Rust实现win下系统信息采集工具的开发 一、 项目目标编写一个 Windows 客户端程序双击运行后静默生成设备信息登记表.xlsx自动提取硬件信息并通过红色底纹提示使用者需要人工补充或排查自动识别失败的数据。技术栈Rust (2021 Edition) sysinfowmirust_xlsxwriter兼容性Win10 / Win11 (64位)二、 项目目录结构system_info_excel/ ├── Cargo.toml # 项目依赖配置文件 ├── src/ │ └── main.rs # 核心逻辑代码 └── target/ # (编译后自动生成包含 release 版本的 .exe)三、 依赖配置文件 (Cargo.toml)[package] name system_info_excel version 1.0.0 edition 2021 [dependencies] sysinfo 0.30 # 获取 CPU、内存、网络、操作系统 wmi 0.13 # 获取底层硬件信息如硬盘序列号、显卡、SN serde { version 1.0, features [derive] } # wmi 的反序列化依赖 rust_xlsxwriter 0.68 # 生成 Excel 表格四、 核心逻辑代码 (src/main.rs)// 隐藏控制台黑框双击直接运行#![windows_subsystem windows]userust_xlsxwriter::{Color,Format,FormatAlign,Workbook};useserde::Deserialize;usestd::fs;usesysinfo::{CpuExt,Networks,System,SystemExt};// WMI 数据结构定义 #[derive(Deserialize)]structWin32_ComputerSystem{Manufacturer:String,Model:String,}#[derive(Deserialize)]structWin32_BIOS{SerialNumber:OptionString,}#[derive(Deserialize)]structWin32_PhysicalMedia{SerialNumber:OptionString,}#[derive(Deserialize)]structWin32_DiskDrive{Size:Optionu64,}#[derive(Deserialize)]structWin32_VideoController{Name:String,}// 错误处理辅助函数 fnsave_error_to_file(msg:str){let_fs::write(System_Info_Error.log,msg);}// 核心主函数 fnmain(){letmutsysSystem::new_all();sys.refresh_all();letnetworksNetworks::new_with_refreshed_list();letwmi_conmatchWMIConnection::new(){Ok(con)con,Err(e){save_error_to_file(format!(WMI 连接失败: {:?},e));return;}};// 1. 获取品牌及型号letbrand_modelmatchwmi_con.query::VecWin32_ComputerSystem(){Ok(data)if!data.is_empty()format!({} {},data[0].Manufacturer,data[0].Model),_未知.to_string(),};// 2. 获取设备SN放最后一列letdevice_snmatchwmi_con.query::VecWin32_BIOS(){Ok(data)if!data.is_empty(){data[0].SerialNumber.clone().unwrap_or_else(||未知.to_string())}_未知.to_string(),};// 3. 获取 CPUletcpusys.cpus().first().map(|c|c.brand().trim().to_string()).unwrap_or_else(||未知.to_string());// 4. 获取内存 (GB)lettotal_ram_gb(sys.total_memory()asf64)/1024.0/1024.0;letramformat!({:.1} GB,total_ram_gb);// 5. 获取显卡 (多个显卡用 隔离)letgpumatchwmi_con.query::VecWin32_VideoController(){Ok(gpus)if!gpus.is_empty(){gpus.iter().map(|g|g.Name.clone()).collect::VecString().join( )}_未知.to_string(),};// 6. 获取硬盘容量 (多个用 隔离)letdisk_capmatchwmi_con.query::VecWin32_DiskDrive(){Ok(disks)if!disks.is_empty(){disks.iter().map(|d|{letsize_gbd.Size.unwrap_or(0)asf64/1_073_741_824.0;format!({:.1} GB,size_gb)}).collect::VecString().join( )}_未知.to_string(),};// 7. 获取硬盘序列号 (多个用 换行符 隔离)letdisk_serialmatchwmi_con.query::VecWin32_PhysicalMedia(){Ok(media)if!media.is_empty(){letserials:VecStringmedia.iter().filter_map(|m|m.SerialNumber.clone()).map(|s|s.replace(*,).trim().to_string()).filter(|s|!s.is_empty()).collect();ifserials.is_empty(){未知.to_string()}else{serials.join(\n)}}_未知.to_string(),};// 8. 获取 MAC 地址letmutmac_list:VecStringVec::new();for(name,data)innetworks{letmacdata.mac_address().to_string();ifmac00:00:00:00:00:00||name.to_lowercase().contains(loopback){continue;}letformatted_macmac.replace(:,-).to_uppercase();letlower_namename.to_lowercase();// 判断网卡类型加中文后缀letentryiflower_name.contains(wi-fi)||lower_name.contains(wlan)||lower_name.contains(wireless){format!({} 无线,formatted_mac)}elseiflower_name.contains(bluetooth)||lower_name.contains(蓝牙){format!({} 蓝牙,formatted_mac)}elseiflower_name.contains(tap)||lower_name.contains(virtual)||lower_name.contains(tunnel){continue;// 排除虚拟网卡}else{formatted_mac};mac_list.push(entry);}letmac_addrifmac_list.is_empty(){未知.to_string()}else{mac_list.join(\n)};// 9. 获取操作系统及版本letos_versionsys.long_os_version().unwrap_or_else(||未知.to_string());// 生成 Excel letmutworkbookWorkbook::new();// 普通表头格式letheader_formatFormat::new().set_bold().set_align(FormatAlign::Center);// 红色提醒格式用于人工填写列或者自动识别失败的值letred_alert_formatFormat::new().set_align(FormatAlign::Center).set_background_color(Color::RGB(0xFFC7CE))// 浅红色背景.set_font_color(Color::RGB(0x9C0006));// 深红色字体letworksheetworkbook.add_worksheet();// 完整表头20列letheaders[序号,设备编号,设备名称,部门,责任人,品牌及型号,CPU,内存,显卡,硬盘容量,硬盘序列号,MAC地址,操作系统及版本,操作系统安装时间,密级,用途,放置地点,使用情况,购机日期启用日期,设备SN];// 写入表头for(col,header)inheaders.iter().enumerate(){let_worksheet.write_with_format(0,colasu16,*header,header_format);}// 辅助函数判断如果数据是未知或空则标红提示fnwrite_with_red_if_fail(worksheet:rust_xlsxwriter::Worksheet,row:u32,col:u16,value:str,red_format:Format,){ifvalue.is_empty()||value未知{let_worksheet.write_with_format(row,col,value,red_format);}else{let_worksheet.write(row,col,value);}}// 填写数据行let_worksheet.write(1,0,1);// 序号默认填1// 自动填入列识别失败则套用红色格式write_with_red_if_fail(worksheet,1,5,brand_model,red_alert_format);// 品牌及型号write_with_red_if_fail(worksheet,1,6,cpu,red_alert_format);// CPUwrite_with_red_if_fail(worksheet,1,7,ram,red_alert_format);// 内存write_with_red_if_fail(worksheet,1,8,gpu,red_alert_format);// 显卡write_with_red_if_fail(worksheet,1,9,disk_cap,red_alert_format);// 硬盘容量write_with_red_if_fail(worksheet,1,10,disk_serial,red_alert_format);// 硬盘序列号write_with_red_if_fail(worksheet,1,11,mac_addr,red_alert_format);// MAC地址write_with_red_if_fail(worksheet,1,12,os_version,red_alert_format);// 操作系统及版本write_with_red_if_fail(worksheet,1,19,device_sn,red_alert_format);// 设备SN放最后// 默认填入固定值的字段let_worksheet.write(1,13,-);// 操作系统安装时间let_worksheet.write(1,14,互联网);// 密级let_worksheet.write(1,15,办公);// 用途let_worksheet.write(1,17,在用);// 使用情况// 必须人工填写的列保持空字符串并强制加红底提醒设备编号、设备名称、部门、责任人、放置地点、购机日期forcolin[1,2,3,4,16,18]{let_worksheet.write_with_format(1,col,,red_alert_format);}// 设置列宽优化阅读体验let_worksheet.set_column_width(0,6);// 序号let_worksheet.set_column_width(1,12);// 设备编号let_worksheet.set_column_width(2,15);// 设备名称let_worksheet.set_column_width(3,12);// 部门let_worksheet.set_column_width(4,12);// 责任人let_worksheet.set_column_width(5,25);// 品牌及型号let_worksheet.set_column_width(6,30);// CPUlet_worksheet.set_column_width(7,15);// 内存let_worksheet.set_column_width(8,35);// 显卡let_worksheet.set_column_width(9,25);// 硬盘容量let_worksheet.set_column_width(10,35);// 硬盘序列号let_worksheet.set_column_width(11,35);// MAC地址let_worksheet.set_column_width(12,30);// 操作系统及版本let_worksheet.set_column_width(13,20);// 操作系统安装时间let_worksheet.set_column_width(14,10);// 密级let_worksheet.set_column_width(15,15);// 用途let_worksheet.set_column_width(16,20);// 放置地点let_worksheet.set_column_width(17,15);// 使用情况let_worksheet.set_column_width(18,25);// 购机日期let_worksheet.set_column_width(19,25);// 设备SN// 保存文件ifletErr(e)workbook.save(设备信息登记表.xlsx){save_error_to_file(format!(保存 Excel 失败: {:?},e));}}五、 编译与使用说明环境准备确保电脑安装了 Rust 开发环境rustup并且安装了 Visual Studio 2022 的 C 桌面开发环境用于 MSVC 链接器。创建项目在终端运行cargo new system_info_excel并进入目录。替换文件将上面的代码分别填入Cargo.toml和src/main.rs。编译运行cargo build --release。分发在target/release/目录下找到system_info_excel.exe把这个文件发给使用 Win10/11 的同事。同事双击后同一个目录下会直接生成填好硬件信息的设备信息登记表.xlsx。如果运行中遇到 WMI 权限问题或提取失败会自动生成System_Info_Error.log日志文件供排查。

相关新闻

2026/8/29 20:32:47

支付宝乘车码坐上海地铁-开票流程

1、支付宝打开【出行】定位到【上海】; 2、选择【地铁】-上海公共交通乘车码-右侧的【查看】; 3、右下角选择【乘车码服务】复制卡号; 4、打开支付宝小程序【上海地铁Metro大都会】-【电子发票】-【公共交通乘车码】; 5、选择地铁…

2026/8/29 20:32:47

非线性规划实战指南:从模型构建到算法求解与MATLAB/Python实现

1. 项目概述:从“线性”到“非线性”的思维跃迁在数学建模的实战中,我们遇到的绝大多数问题,其本质都是“非线性”的。回想一下,当你试图优化一个工厂的生产计划,利润和成本往往不是简单的倍数关系;当你预测…

2026/8/29 20:32:47

蓝桥杯国赛真题解析:状态压缩动态规划解决矩阵计数问题

1. 项目概述:从一道国赛真题看状态压缩动态规划的精髓 最近在复盘历年蓝桥杯国赛的真题,2019年那道的“矩阵计数”题让我印象尤为深刻。这不仅仅是一道编程题,更像是一个窗口,让我们能窥见“状态压缩动态规划”(State …

2026/8/29 20:42:49

基于SpringBoot的谷田周边商城系统(源代码+文档+PPT+调试+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/29 20:42:49

Python入门实战:从零构建猜数字游戏,掌握核心编程逻辑

1. 项目概述:为什么从《猜数字》开始你的Python之旅?如果你刚接触Python,或者想找个有趣的项目练手,把“猜数字”这个小游戏作为起点,绝对是个聪明又高效的选择。这项目标题“Python小游戏《猜数字》”听起来简单&…

2026/8/29 20:42:49

432道MySQL面试题 161 - 180 题

为方便阅读,这里整理了整个系列的索引导航。本系列共 432 道 MySQL 面试题,按每 20 题为一篇进行连载,点击下方链接即可跳转到对应章节,方便你按需查阅、系统复习。 432道MySQL面试题 1 - 20 题 432道MySQL面试题 21 - 40 题 432道MySQL面试题 41 - 60 题 432道MySQL面试题…

2026/8/29 20:42:49

蓝桥杯递增序列问题解析:贪心算法与边界处理实战

1. 从一个看似简单的题目说起最近在整理历年算法竞赛的真题时,我又翻到了第十届蓝桥杯国赛JAVA B组的“递增序列”这道题。说实话,第一次看到这个标题,很多人的第一反应可能和我当初一样:“递增序列?这还不简单&#x…

2026/8/29 20:37:48

DAC输出波形最大频率的工程实践:从理论到实测的全面解析

1. 项目缘起:一个看似简单却暗藏玄机的问题 “DAC输出波形的最大频率是多少?” 这个问题,乍一听像是电子工程师或者嵌入式开发者随口就能回答的。很多人的第一反应可能是去查数据手册,找到DAC的“建立时间”参数,然后用…

2026/8/28 16:16:17

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/28 16:16:21

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/28 16:16:22

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/29 0:01:10

etc目录下的profile.d文件目录设置环境变量和全局脚本shell

一、设置环境变量etc目录下的profile.d文件目录 /etc/profile.d1、编写 vi test.sh文件内容# jdk变量 export ZHK_HOME/root export PATH$PATH:$ZHK_HOME/test # 可以取出来ZHK_HOME变量给ZZZ_HOME赋值 export ZZZ_HOME${ZHK_HOME}/test2、刷新 执行source /etc/profile 命令使…

2026/8/29 0:01:10

【JavaScript】内存管理-垃圾回收机制-内存泄露

内存管理 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()。 而 JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。释放的过程称为垃圾回收。 整…

2026/8/29 0:01:10

Labgrid-MCP:为嵌入式硬件实验室接入AI Agent操控能力

Labgrid-MCP 的目标是把 MCP(Model Context Protocol)能力延伸到真实嵌入式硬件实验室:AI Agent 通过一个标准化的 MCP Server,就能查看目标板状态、控制上电断电、复位开发板、读取串口日志,甚至执行镜像刷写。对于经…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…