在系统监控、设备管理或自动化运维场景中,获取操作系统的详细信息是一项基础且重要的工作。Go语言凭借其跨平台特性和简洁的语法,成为开发这类工具的理想选择。本文将详细介绍如何使用Go语言获取Windows系统的全方位信息,包括操作系统、CPU、内存、磁盘、网络、BIOS、主板及电池状态等。
技术准备:核心库介绍
要实现Windows系统信息的获取,我们主要依赖两个关键库:
- gopsutil:一个跨平台的系统监控库,支持CPU、内存、磁盘、网络等基础信息的获取,简化了跨平台开发的复杂度。
- go-ole:用于访问Windows的COM接口,通过它可以调用WMI(Windows Management Instrumentation)服务,获取BIOS、主板、电池等硬件级信息。
安装依赖:
bash
go get github.com/shirou/gopsutil/v3
go get github.com/go-ole/go-ole
数据结构设计:统一信息组织方式
为了清晰地组织和输出系统信息,我们定义了一套结构化的数据模型,将不同类型的信息分类存储:
go
// 系统信息总结构体
type SystemInfo struct {
OSInfo OSInfo `json:"os_info"` // 操作系统信息
UserInfo UserInfo `json:"user_info"` // 当前用户信息
CPUInfo CPUInfo `json:"cpu_info"` // CPU信息
MemoryInfo MemoryInfo `json:"memory_info"` // 内存信息
DiskInfo []DiskInfo `json:"disk_info"` // 磁盘信息
NetworkInfo []NetworkInfo `json:"network_info"` // 网络信息
BiosInfo BiosInfo `json:"bios_info"` // BIOS信息
Motherboard Motherboard `json:"motherboard"` // 主板信息
BatteryInfo *BatteryInfo `json:"battery_info"` // 电池信息(仅笔记本)
}
// 嵌套的子结构体(示例)
type OSInfo struct {
Name string `json:"name"` // 系统名称
Version string `json:"version"` // 系统版本
Build string `json:"build"` // 系统构建号
Platform string `json:"platform"` // 平台
KernelVersion string `json:"kernel_version"` // 内核版本
BootTime time.Time `json:"boot_time"` // 启动时间
Uptime string `json:"uptime"` // 运行时长
}
这些结构体通过JSON标签序列化后,可直接输出为易读的JSON格式,便于后续处理和展示。
核心实现:分模块获取信息
1. 操作系统信息获取
通过gopsutil/host
包可以轻松获取操作系统的基础信息,包括名称、版本、启动时间等:
go
func getOSInfo() OSInfo {
hostInfo, _ := host.Info()
bootTime := time.Unix(int64(hostInfo.BootTime), 0) // 转换启动时间为time.Time
uptime := time.Since(bootTime).Round(time.Second) // 计算运行时长
return OSInfo{
Name: hostInfo.OS,
Version: hostInfo.PlatformVersion,
Build: hostInfo.KernelVersion,
Platform: hostInfo.Platform,
KernelVersion: hostInfo.KernelVersion,
BootTime: bootTime,
Uptime: uptime.String(),
}
}
2. 当前用户信息
使用Go标准库的os/user
和os
包获取当前登录用户的用户名和家目录:
go
func getUserInfo() UserInfo {
currentUser, err := user.Current()
if err != nil {
return UserInfo{Username: "unknown", HomeDir: "unknown"}
}
homeDir, err := os.UserHomeDir()
if err != nil {
homeDir = "unknown"
}
return UserInfo{
Username: currentUser.Username,
HomeDir: homeDir,
}
}
3. CPU信息获取
gopsutil/cpu
包提供了CPU的详细信息,包括型号、核心数、主频等:
go
func getCPUInfo() CPUInfo {
cpuInfos, _ := cpu.Info()
logicalCores, _ := cpu.Counts(true) // 逻辑核心数
if len(cpuInfos) == 0 {
return CPUInfo{}
}
info := cpuInfos[0]
return CPUInfo{
ModelName: info.ModelName, // 例如:Intel(R) Core(TM) i7-10700K
PhysicalCores: int(info.Cores), // 物理核心数
LogicalCores: logicalCores, // 逻辑核心数(考虑超线程)
Mhz: info.Mhz, // 主频(MHz)
VendorID: info.VendorID, // 厂商ID(例如:GenuineIntel)
}
}
4. 内存信息获取
通过gopsutil/mem
获取内存总量、可用量及使用率,并转换为GB单位便于阅读:
go
func getMemoryInfo() MemoryInfo {
memInfo, _ := mem.VirtualMemory()
return MemoryInfo{
TotalGB: float64(memInfo.Total) / 1024 / 1024 / 1024, // 总内存(GB)
AvailableGB: float64(memInfo.Available) / 1024 / 1024 / 1024, // 可用内存(GB)
UsedGB: float64(memInfo.Used) / 1024 / 1024 / 1024, // 已用内存(GB)
UsagePercent: memInfo.UsedPercent, // 使用率(%)
}
}
5. 磁盘信息获取
遍历所有磁盘分区,获取每个分区的设备名、挂载点及容量信息:
go
func getDiskInfo() []DiskInfo {
partitions, _ := disk.Partitions(true) // 获取所有分区(包括虚拟分区)
var diskInfos []DiskInfo
for _, part := range partitions {
usage, err := disk.Usage(part.Mountpoint)
if err != nil {
continue // 跳过无法访问的分区
}
diskInfos = append(diskInfos, DiskInfo{
Device: part.Device, // 设备名(例如:C:\\)
Mountpoint: part.Mountpoint, // 挂载点
FSType: part.Fstype, // 文件系统(例如:NTFS)
TotalGB: float64(usage.Total) / 1024 / 1024 / 1024,
FreeGB: float64(usage.Free) / 1024 / 1024 / 1024,
UsedGB: float64(usage.Used) / 1024 / 1024 / 1024,
UsagePercent: usage.UsedPercent,
})
}
return diskInfos
}
6. 网络信息获取
通过标准库net
获取网卡信息(名称、MAC地址、IP地址),并通过WMI查询网关地址:
go
func getNetworkInfo() []NetworkInfo {
ifaces, _ := net.Interfaces() // 获取所有网络接口
var netInfos []NetworkInfo
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // 跳过未启用的网卡
}
// 提取IPv4和IPv6地址
var ipv4, ipv6 []string
addrs, _ := iface.Addrs()
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if !ok {
continue
}
ip := ipNet.IP.String()
if ipNet.IP.To4() != nil {
ipv4 = append(ipv4, ip)
} else {
ipv6 = append(ipv6, ip)
}
}
// 通过WMI获取网关
gateway := getGateway(iface.Name)
netInfos = append(netInfos, NetworkInfo{
Name: iface.Name,
MAC: iface.HardwareAddr.String(),
IPv4: ipv4,
IPv6: ipv6,
Gateway: gateway,
})
}
return netInfos
}
7. BIOS与主板信息(基于WMI)
Windows的硬件信息(如BIOS、主板)需要通过WMI查询。我们封装了通用的WMI查询函数:
go
// 通用WMI查询函数
func queryWMI(query string) ([]map[string]interface{}, error) {
service, err := createWMIService() // 创建WMI服务连接
if err != nil || service == nil {
return nil, err
}
defer service.Release()
// 执行查询并解析结果(省略具体实现)
// ...
}
// 获取BIOS信息
func getBiosInfo() BiosInfo {
data, _ := queryWMI("SELECT Manufacturer, Version, ReleaseDate FROM Win32_BIOS")
if len(data) == 0 {
return BiosInfo{}
}
return BiosInfo{
Manufacturer: getStringFromMap(data[0], "Manufacturer"),
Version: getStringFromMap(data[0], "Version"),
ReleaseDate: getStringFromMap(data[0], "ReleaseDate"),
}
}
// 获取主板信息
func getMotherboardInfo() Motherboard {
data, _ := queryWMI("SELECT Manufacturer, Product FROM Win32_BaseBoard")
if len(data) == 0 {
return Motherboard{}
}
return Motherboard{
Manufacturer: getStringFromMap(data[0], "Manufacturer"),
Model: getStringFromMap(data[0], "Product"),
}
}
8. 电池信息(针对笔记本)
通过WMI查询Win32_Battery
类获取电池状态:
go
func getBatteryInfo() *BatteryInfo {
data, _ := queryWMI(`SELECT DesignCapacity, FullChargeCapacity,
CurrentCapacity, EstimatedChargeRemaining, Status FROM Win32_Battery`)
if len(data) == 0 {
return nil // 台式机可能无电池,返回nil
}
item := data[0]
status := ""
switch getIntFromMap(item, "Status") {
case 1:
status = "放电中"
case 2:
status = "充电中"
case 3:
status = "充满电"
default:
status = "未知"
}
return &BatteryInfo{
DesignCapacity: getIntFromMap(item, "DesignCapacity"),
FullChargeCapacity: getIntFromMap(item, "FullChargeCapacity"),
CurrentCapacity: getIntFromMap(item, "CurrentCapacity"),
ChargePercent: getIntFromMap(item, "EstimatedChargeRemaining"),
Status: status,
}
}
整合与输出
在main
函数中整合所有信息,并序列化为JSON输出:
go
func main() {
ole.CoInitialize(0) // 初始化COM(WMI依赖)
defer ole.CoUninitialize()
// 收集所有系统信息
sysInfo := SystemInfo{
OSInfo: getOSInfo(),
UserInfo: getUserInfo(),
CPUInfo: getCPUInfo(),
MemoryInfo: getMemoryInfo(),
DiskInfo: getDiskInfo(),
NetworkInfo: getNetworkInfo(),
BiosInfo: getBiosInfo(),
Motherboard: getMotherboardInfo(),
BatteryInfo: getBatteryInfo(),
}
// 输出为格式化的JSON
jsonData, _ := json.MarshalIndent(sysInfo, "", " ")
fmt.Println(string(jsonData))
}
运行结果示例
执行程序后,会输出类似以下的JSON结果(简化版):
json
{
"os_info": {
"name": "Microsoft Windows 10 Pro",
"version": "10.0.19045",
"boot_time": "2023-10-01T08:30:00+08:00",
"uptime": "5h30m0s"
},
"cpu_info": {
"model_name": "Intel(R) Core(TM) i7-10700K",
"physical_cores": 8,
"logical_cores": 16,
"mhz": 3800.0
},
"memory_info": {
"total_gb": 31.9,
"available_gb": 15.2,
"usage_percent": 52.4
}
// ... 其他信息省略
}
总结
本文通过Go语言结合gopsutil
和go-ole
库,实现了Windows系统全方位信息的获取。核心思路是:
- 利用
gopsutil
获取跨平台通用信息(CPU、内存、磁盘等); - 通过WMI(借助
go-ole
)获取Windows特有的硬件信息(BIOS、主板、电池等); - 用结构化数据模型组织信息,最终输出为易读的JSON格式。
这种方案既利用了gopsutil
的便捷性,又通过WMI补充了Windows特有的硬件细节,适合开发Windows系统监控工具、设备管理软件等场景。如需扩展,可进一步查询WMI的其他类(如Win32_VideoController
获取显卡信息),实现更全面的系统监控。