我如何使用C#读取扩展智能数据?

我知道一些C + +和Java,但我想自己学习C#。 混乱,我试图读取我的硬盘驱动器的SMART数据。 我有这个C#代码,但我不知道如何修改它来读取额外的内存值:它显然读取“值”值,而不是“最差”或“阈值”值。 我想将这两个数据值(最差和阈值)添加到程序中。 如何做到这一点将有助于我学习一点C#。

C#示例:(我想要使用的)

// (c) Microsoft Corporation // Author: Clemens Vasters (clemensv@microsoft.com) // Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html // SMART Attributes and Background: http://en.wikipedia.org/wiki/SMART // 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和1未知通常为零-2属性-3状态-4未知通常为零-5值-6最差-7,8原始值-9,10,11未知通常为零

我在这里发现这些: http : //www.i-programmer.info/projects/38-windows/208-disk-drive-dangers.html?start=2

Solutions Collecting From Web of "我如何使用C#读取扩展智能数据?"

请注意,并非所有SMART HDD信息都可以从单个WMI查询中获取。

您需要查询以下所有内容以确定当前值,最差值,阈值,驱动器状态和属性状态:

Win32_DiskDrive MSStorageDriver_FailurePredictStatus MSStorageDriver_FailurePredictData MSStorageDriver_FailurePredictThresholds

有关C#/ WMI全面解决方案的详细信息,请参阅此解决方案http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx (请注意:我拥有此开发博客)