2011-12-29 2 views
2

저는 C++과 Java를 약간 알고 있지만 C#을 배우고 자합니다. 엉망으로, 나는 내 하드 드라이브의 스마트 데이터를 읽으려고합니다. 이 C# 코드가 있지만 추가 메모리 값을 읽는 방법을 수정하는 방법을 모르겠습니다. 분명히 '값'값은 읽지 만 '최하위'또는 '임계 값'값은 읽지 않습니다. 이 두 데이터 값 (최악 및 임계 값)을 프로그램에 추가하고 싶습니다. 이 방법을 이해하면 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 다음의 바이트를 변수 다음에 asign하여 변수에 저장하는 법입니다. "public struct SmartAttribute"에 있어야한다고 생각합니다 ... – user1120389

답변

2

참고.

당신은 모든 현재 값을 결정하기 위해 다음과 같은, 최악의 값, 임계 값, 드라이브 상태를 조회 및 상태 속성해야합니다 MSStorageDriver_FailurePredictStatus MSStorageDriver_FailurePredictData을

Win32_DiskDrive을 MSStorageDriver_FailurePredictThresholds C#에서 포괄적 인 솔루션에 대한

/관련 SMART HDD 정보를 자세히 설명하는 WMI http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx (참고 :이 개발 블로그를 소유하고 있음)

+0

감사합니다 Andrew, ok. 내 소식을 업데이트하겠습니다. – TheLegendaryCopyCoder