2011-12-29 29 views
2

私はC++とJavaを少しは知っていますが、自分でC#を学びたいと思っています。私のハードドライブのSMARTデータを読み込もうとしています。私はこのC#コードを持っていますが、追加のメモリ値を読み込むためにそれを変更する方法はわかりません:明らかに 'Value'値を読み込みますが、 'Worst'または 'Threshold'値は読みません。これら2つのデータ値(WorstとThreshold)をプログラムに追加したいと思います。これを行う方法を考えると、C#を少し学ぶのに役立ちます。C#の使用方法拡張スマートデータを読み込むには?

C#例:(私が使用したいどのような)

// (c) Microsoft Corporation 
// Author: Clemens Vasters ([email protected]) 
// Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html 
// SMART Attributes and Background: http://en.wikipedia.org/wiki/S.M.A.R.T. 
// SMART Attributes Overview: http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf 

namespace SmartDataApp 
{ 
using System; 
using System.Collections.Generic; 
using System.Management; 
using System.Runtime.InteropServices; 

public enum SmartAttributeType : byte 
{ 
    ReadErrorRate = 0x01, 
    ThroughputPerformance = 0x02, 
    SpinUpTime = 0x03, 
    StartStopCount = 0x04, 
    ReallocatedSectorsCount = 0x05, 
    ReadChannelMargin = 0x06, 
    SeekErrorRate = 0x07, 
    SeekTimePerformance = 0x08, 
    PowerOnHoursPOH = 0x09, 
    SpinRetryCount = 0x0A, 
    CalibrationRetryCount = 0x0B, 
    PowerCycleCount = 0x0C, 
    SoftReadErrorRate = 0x0D, 
    SATADownshiftErrorCount = 0xB7, 
    EndtoEnderror = 0xB8, 
    HeadStability = 0xB9, 
    InducedOpVibrationDetection = 0xBA, 
    ReportedUncorrectableErrors = 0xBB, 
    CommandTimeout = 0xBC, 
    HighFlyWrites = 0xBD, 
    AirflowTemperatureWDC = 0xBE, 
    TemperatureDifferencefrom100 = 0xBE, 
    GSenseErrorRate = 0xBF, 
    PoweroffRetractCount = 0xC0, 
    LoadCycleCount = 0xC1, 
    Temperature = 0xC2, 
    HardwareECCRecovered = 0xC3, 
    ReallocationEventCount = 0xC4, 
    CurrentPendingSectorCount = 0xC5, 
    UncorrectableSectorCount = 0xC6, 
    UltraDMACRCErrorCount = 0xC7, 
    MultiZoneErrorRate = 0xC8, 
    WriteErrorRateFujitsu = 0xC8, 
    OffTrackSoftReadErrorRate = 0xC9, 
    DataAddressMarkerrors = 0xCA, 
    RunOutCancel = 0xCB, 
    SoftECCCorrection = 0xCC, 
    ThermalAsperityRateTAR = 0xCD, 
    FlyingHeight = 0xCE, 
    SpinHighCurrent = 0xCF, 
    SpinBuzz = 0xD0, 
    OfflineSeekPerformance = 0xD1, 
    VibrationDuringWrite = 0xD3, 
    ShockDuringWrite = 0xD4, 
    DiskShift = 0xDC, 
    GSenseErrorRateAlt = 0xDD, 
    LoadedHours = 0xDE, 
    LoadUnloadRetryCount = 0xDF, 
    LoadFriction = 0xE0, 
    LoadUnloadCycleCount = 0xE1, 
    LoadInTime = 0xE2, 
    TorqueAmplificationCount = 0xE3, 
    PowerOffRetractCycle = 0xE4, 
    GMRHeadAmplitude = 0xE6, 
    DriveTemperature = 0xE7, 
    HeadFlyingHours = 0xF0, 
    TransferErrorRateFujitsu = 0xF0, 
    TotalLBAsWritten = 0xF1, 
    TotalLBAsRead = 0xF2, 
    ReadErrorRetryRate = 0xFA, 
    FreeFallProtection = 0xFE, 
} 

public class SmartData 
{ 
    readonly Dictionary<SmartAttributeType, SmartAttribute> attributes; 
    readonly ushort structureVersion; 

    public SmartData(byte[] arrVendorSpecific) 
    { 
     attributes = new Dictionary<SmartAttributeType, SmartAttribute>(); 
     for (int offset = 2; offset < arrVendorSpecific.Length;) 
     { 
      var a = FromBytes<SmartAttribute>(arrVendorSpecific, ref offset, 12); 
      // Attribute values 0x00, 0xfe, 0xff are invalid 
      if (a.AttributeType != 0x00 && (byte)a.AttributeType != 0xfe && (byte)a.AttributeType != 0xff) 
      { 
       attributes[a.AttributeType] = a; 
      } 
     } 
     structureVersion = (ushort)(arrVendorSpecific[0] * 256 + arrVendorSpecific[1]); 
    } 

    public ushort StructureVersion 
    { 
     get 
     { 
      return this.structureVersion; 
     } 
    } 

    public SmartAttribute this[SmartAttributeType v] 
    { 
     get 
     { 
      return this.attributes[v]; 
     } 
    } 

    public IEnumerable<SmartAttribute> Attributes 
    { 
     get 
     { 
      return this.attributes.Values; 
     } 
    } 

    static T FromBytes<T>(byte[] bytearray, ref int offset, int count) 
    { 
     IntPtr ptr = IntPtr.Zero; 

     try 
     { 
      ptr = Marshal.AllocHGlobal(count); 
      Marshal.Copy(bytearray, offset, ptr, count); 
      offset += count; 
      return (T)Marshal.PtrToStructure(ptr, typeof(T)); 
     } 
     finally 
     { 
      if (ptr != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(ptr); 
      } 
     } 
    } 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct SmartAttribute 
{ 
    public SmartAttributeType AttributeType; 
    public ushort Flags; 
    public byte Value; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 
    public byte[] VendorData; 

    public bool Advisory 
    { 
     get 
     { 
      return (Flags & 0x1) == 0x0; // Bit 0 unset? 
     } 
    } 
    public bool FailureImminent 
    { 
     get 
     { 
      return (Flags & 0x1) == 0x1; // Bit 0 set? 
     } 
    } 
    public bool OnlineDataCollection 
    { 
     get 
     { 
      return (Flags & 0x2) == 0x2; // Bit 0 set? 
     } 
    } 

} 

public class Program 
{ 
    public static void Main() 
    { 
     try 
     { 
      var searcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSStorageDriver_ATAPISmartData"); 

      foreach (ManagementObject queryObj in searcher.Get()) 
      { 
       Console.WriteLine("-----------------------------------"); 
       Console.WriteLine("MSStorageDriver_ATAPISmartData instance"); 
       Console.WriteLine("-----------------------------------"); 

       var arrVendorSpecific = (byte[])queryObj.GetPropertyValue("VendorSpecific"); 

       // Create SMART data from 'vendor specific' array 
       var d = new SmartData(arrVendorSpecific); 
       foreach (var b in d.Attributes) 
       { 
        Console.Write("{0} :{1} : ", b.AttributeType, b.Value); 
        foreach (byte vendorByte in b.VendorData) 
        { 
         Console.Write("{0:x} ", vendorByte); 
        } 
        Console.WriteLine(); 
       } 

      } 
     } 
     catch (ManagementException e) 
     { 
      Console.WriteLine("An error occurred while querying for WMI data: " + e.Message); 
     } 
    } 
} 

}

大きな問題は、それが本当に「特定のベンダー」であるとして、それはすべてが何を意味するかを考え出すです。データは、属性データの12バイトブロックに編成される。配列の最初のバイトは、属性ブロックの数を示します。各属性ブロックのフォーマットを有する:

項目データ -0及び1Unknown通常ゼロ -2項目-3ステータス -4不明通常ゼロ -5値-6最悪 -7,8-生の値 -9,10,11ゼロ

通常不明私はここでこれらを発見した:すべてのSMART HDDの情報を単一のWMIクエリから取得することができないというhttp://www.i-programmer.info/projects/38-windows/208-disk-drive-dangers.html?start=2

+0

理解されていないもの)は、Valueの後の次のバイトを変数に代入して保存する方法です。 "パブリック構造体SmartAttribute"にする必要があります... – user1120389

答えて

2

注意を。

あなたはすべての現在の値、最悪値、しきい値、ドライブのステータスと属性のステータスを確認するには、次のクエリを実行する必要があります/ C#での総合的なソリューションについては

Win32_DiskDrive MSStorageDriver_FailurePredictStatus MSStorageDriver_FailurePredictData MSStorageDriver_FailurePredictThresholds

を関連するすべてのSMART HDD情報を詳しく説明しているWMI http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx(注:私はこの開発ブログを持っています)

+0

ありがとうAndrew、okが行います。私は自分の投稿を更新します。 – TheLegendaryCopyCoder

関連する問題