windows 如何使用 C# 读取扩展智能数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8663980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use C# To read extended smart data?
提问by user1120389
I know a bit of C++ and Java, but am wanting to learn c# on my own. To mess with, I'm trying to read the SMART data of my hard drive. I have this C# Code, but I do not know how to modify it to read an additional memory value: It apparently reads the 'Value' value but not the 'Worst' or 'Threshold' value. I want to add these two data values (Worst and Threshold) to the program. Figuring how to do this will help me learn C# a little.
我知道一点 C++ 和 Java,但我想自学 C#。麻烦的是,我正在尝试读取硬盘驱动器的 SMART 数据。我有这个 C# 代码,但我不知道如何修改它以读取额外的内存值:它显然读取的是“值”值,而不是“最差”或“阈值”值。我想将这两个数据值(最差和阈值)添加到程序中。弄清楚如何做到这一点将帮助我学习 C# 一点点。
C# Example: (What I want to use)
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);
}
}
}
}
}
The big problem is in figuring out what it all means as it really is “vendor specific”. The data is organised into 12 byte blocks of attribute data. The first byte of the array gives the number of attribute blocks. Each attribute block has the format:
最大的问题是弄清楚这一切意味着什么,因为它确实是“特定于供应商的”。数据被组织成 12 字节的属性数据块。数组的第一个字节给出了属性块的数量。每个属性块都具有以下格式:
Item Data -0 and 1Unknown usually zero -2 Attribute -3 Status -4 Unknown usually zero -5 Value -6 Worst -7,8 Raw Value -9,10,11 Unknown usually zero
项目数据 -0 和 1Unknown 通常为零 -2 属性 -3 Status -4 Unknown 通常为零 -5 Value -6 Worst -7,8 Raw Value -9,10,11 Unknown 通常为零
I found these here: http://www.i-programmer.info/projects/38-windows/208-disk-drive-dangers.html?start=2
我在这里找到了这些:http: //www.i-programmer.info/projects/38-windows/208-disk-drive-dangers.html?start=2
回答by TheLegendaryCopyCoder
Note that not all SMART HDD info can be obtained from a single WMI query.
请注意,并非所有 SMART HDD 信息都可以从单个 WMI 查询中获得。
You need to query all the following to determine the current value, worst value, threshold, drive status and attribute status:
您需要查询以下所有内容以确定当前值、最差值、阈值、驱动器状态和属性状态:
- Win32_DiskDrive
- MSStorageDriver_FailurePredictStatus
- MSStorageDriver_FailurePredictData
- MSStorageDriver_FailurePredictThresholds
- Win32_磁盘驱动器
- MSStorageDriver_FailurePredictStatus
- MSStorageDriver_FailurePredictData
- MSStorageDriver_FailurePredictThresholds
For a comprehensive solution in C#/WMI detailing all relevant SMART HDD info see this solution http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx(please note: I own this development blog)
有关 C#/WMI 中详细说明所有相关 SMART HDD 信息的综合解决方案,请参阅此解决方案http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx(请注意:我拥有此开发博客)