为了开发硬盘分析工具,我试图从硬盘的 S.M.A.R.T 数据中获取加载/卸载周期计数的值,我想知道是否有人知道如何执行此操作。
我正在尝试什么:

  • 我正在搜索 WMI MSStorageDriver_ATAPISmartData 类数据,其中属性编号 193 是我需要的(表示加载/卸载循环计数的属性)
  • 我得到的数据看起来像


  • 我想我很接近,红色的数据与我运行它时珠穆朗玛峰家庭版显示的数据相同,理想情况下我想要最后一部分(称为数据的属性)

    收集这些数据的方法:
    static void doStuff()
    {
        try
        {
    
            byte TEMPERATURE_ATTRIBUTE = 193;
    
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"\root\WMI", "SELECT * FROM MSStorageDriver_ATAPISmartData");
            //loop through all the hard disks
            foreach (ManagementObject queryObj in searcher.Get())
            {
                byte[] arrVendorSpecific = (byte[])queryObj.GetPropertyValue("VendorSpecific");
    
                int tempIndex = Array.IndexOf(arrVendorSpecific, TEMPERATURE_ATTRIBUTE);
                Console.WriteLine("HDD TEMP: " + arrVendorSpecific[tempIndex + 5].ToString());
    
                foreach (byte dat in arrVendorSpecific)
                {
                    Console.Write(dat.ToString() + " ");
                }
            }
    
        }
        catch (Exception err) { Console.WriteLine(err.Message); }
    }
    

    附言这种方法适用于收集硬盘的温度(这就是 Console.WriteLine("HDD TEMP: " + arrVendorSpecific[tempIndex + 5].ToString()); 行的全部内容,但我不确定为什么它的 tempIndex+5

    最佳答案

    您使用的代码不正确,因为您正在使用安全搜索 (Array.IndexOf) 来查找 SMART Attribute ID(您可能会误报,因为该值可以与数组中的另一个值匹配),这些属性的 ID在已记录的结构 ( SMART Attribute Overview ) 中具有固定位置。

    SMART 属性表

    Offset  Length  Description
            (bytes)
    0         2      SMART structure version (this is vendor-specific)
    2         12     Attribute entry 1
    2+(12)    12     Attribute entry 2
    . . .
    2+(12*29) 12     Attribute entry 30
    

    属性表中的条目

    从这里您可以编写代码来搜索每个属性的位置并获取您正在寻找的值
    using System;
    using System.Collections.Generic;
    using System.Management;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace GetWMI_Info
    {
        class Program
        {
    
            [StructLayout(LayoutKind.Sequential)]
            public struct Attribute
            {
                public byte AttributeID;
                public ushort Flags;
                public byte Value;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
                public byte[] VendorData;
            }
    
            static void Main(string[] args)
            {
                try
                {
                    Attribute AtributeInfo;
                    ManagementScope Scope = new ManagementScope(String.Format("\\\\{0}\\root\\WMI", "localhost"), null);
                    Scope.Connect();
                    ObjectQuery Query = new ObjectQuery("SELECT VendorSpecific FROM MSStorageDriver_ATAPISmartData");
                    ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
                    byte LoadCycleCount = 0xC1;
                    int Delta  = 12;
                    foreach (ManagementObject WmiObject in Searcher.Get())
                    {
                        byte[] VendorSpecific = (byte[])WmiObject["VendorSpecific"];
                        for (int offset = 2; offset < VendorSpecific.Length; )
                        {
                            if (VendorSpecific[offset] == LoadCycleCount)
                            {
    
                                IntPtr buffer = IntPtr.Zero;
                                try
                                {
                                    buffer = Marshal.AllocHGlobal(Delta);
                                    Marshal.Copy(VendorSpecific, offset, buffer, Delta);
                                    AtributeInfo = (Attribute)Marshal.PtrToStructure(buffer, typeof(Attribute));
                                    Console.WriteLine("AttributeID {0}", AtributeInfo.AttributeID);
                                    Console.WriteLine("Flags {0}", AtributeInfo.Flags);
                                    Console.WriteLine("Value {0}", AtributeInfo.Value);
                                    Console.WriteLine("Value {0}", BitConverter.ToString(AtributeInfo.VendorData));
                                }
                                finally
                                {
                                    if (buffer != IntPtr.Zero)
                                    {
                                        Marshal.FreeHGlobal(buffer);
                                    }
                                }
                            }
                            offset += Delta;
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
                }
                Console.WriteLine("Press Enter to exit");
                Console.Read();
            }
        }
    }
    

    关于c# - 使用 S.M.A.R.T 和 WMI 加载/卸载循环计数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9852979/

    10-13 07:09