Go-使用wmi获取硬盘smart信息并解析

2021-06-07  本文已影响0人  Bug2Coder
import (
    "fmt"
    "strconv"
    "github.com/StackExchange/wmi"
)

const (
    Power_On_Hours      = 9
    Power_Cycle_Count   = 12
    Temperature_Celsius = 194
)

var smartProperties = map[uint8]string{
    Power_On_Hours:      "通电总时长",
    Power_Cycle_Count:   "通电次数",
}

// MSStorageDriver_ATAPISmartData 硬盘smart信息
type MSStorageDriver_ATAPISmartData struct {
    Active             bool
    Checksum           uint8
    ErrorLogCapability uint8
    //ExtendPollTimeInMinutes  uint8
    InstanceName             string
    Length                   uint32
    OfflineCollectCapability uint8
    OfflineCollectionStatus  uint8
    Reserved                 []uint8
    SelfTestStatus           uint8
    //ShortPollTimeMinutes     uint8
    SmartCapability uint16
    TotalTime       uint16
    VendorSpecific  []uint8
    VendorSpecific2 uint8
    VendorSpecific3 uint8
    VendorSpecific4 []uint8
}

func GetDiskSmartData() {
    var sd []MSStorageDriver_ATAPISmartData
    err := wmi.QueryNamespace("Select * from MSStorageDriver_ATAPISmartData", &sd, "root\\WMI")
    if err != nil {
        fmt.Println("err", err)
        return
    }
    for _, v := range sd {
        result := SplitUintN(v.VendorSpecific[2:], 12)
        if result != nil {
            data := parseSmartData(result)
            fmt.Println("硬盘信息:",v.InstanceName)
            fmt.Println(data)
        }
    }
}

// 解析smart消息
func parseSmartData(data [][]uint8) string {
    var result string
    for _, v := range data {
        if len(v) != 12 {
            continue
        }
        v5 := int(v[5])
        v6 := int(v[6]) * 16 * 16
        v7 := int(v[7]) * 16 * 16 * 16
        p := v5 + v6 + v7
        switch v[0] {
        case Power_On_Hours:
            result += smartProperties[Power_On_Hours] + ":" + strconv.Itoa(p) + "\n"
        case Power_Cycle_Count:
            result += smartProperties[Power_Cycle_Count] + ":" + strconv.Itoa(p) + "\n"
        }
    }
    return result
}

// SplitUintN 按给定的长度进行分割
func SplitUintN(source []uint8, size int) [][]uint8 {
    if len(source) < size || size <= 0 {
        return nil
    }
    result := make([][]uint8, 0)
    for i := 0; i < len(source)/size; i++ {
        if source[i*size] == 0 {
            continue
        }
        if len(source[i*size:]) > size {
            result = append(result, source[i*size:i*size+size])
        } else {
            result = append(result, source[i*size:])
        }
    }
    return result
}
上一篇下一篇

猜你喜欢

热点阅读