2012-03-24 156 views
4

在试图开发硬盘分析工具时,我试图从硬盘的SMART数据中获取加载/卸载周期数的值,我想知道是否有人知道如何做到这一点。 我想要:使用SMART和WMI加载/卸载周期数

  1. 我搜索WMI MSStorageDriver_ATAPISmartData类数据,其中属性数量193是我需要
  2. 的数据我收到的外观(占加载/卸载循环次数的属性)像

enter image description here

我觉得我很近,红色的数据是一样的东西珠峰家庭版显示了当我运行它,理想我想最后一部分是(属性称为数据)

用于收集该数据

enter image description here

方法:

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); } 
} 

P.S.这种方法适用于收集硬盘的温度(这是什么Console.WriteLine("HDD TEMP: " + arrVendorSpecific[tempIndex + 5].ToString());线是关于,但我不知道为什么它的tempIndex + 5

回答

8

您使用的代码是不正确的,因为您正在使用一个secuencial搜索( Array.IndexOf)来查找SMART Attribute ID(可以假阳性,因为该值可以与另一个阵列中的匹配)时,这些attibutes的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 

项的属性表

enter image description here

从这里你可以写代码来搜索每个属性的位置,让您正在寻找

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(); 
     } 
    } 
}