我知道一点C++和Java,但我想自己学习C#.为了搞砸,我试图读取我的硬盘驱动器的SMART数据.我有这个C#代码,但我不知道如何修改它读取额外的内存值:它显然读取的是“Value”值,而不是“Worst”或“Threshold”值。(最差和阈值)到程序。弄清楚如何做到这一点将有助于我学习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和1未知通常为零属性-3状态-4未知通常为零值-6最差-7,8原始值-9,10,11未知通常为零
我在这里找到这些:http://www.i-programmer.info/projects/38-windows/208-disk-drive-dangers.html?start=2
1条答案
按热度按时间ippsafx71#
请注意,并非所有SMART HDD(不包括USB和NVME驱动器)信息都可以从单个查询中获得。
您需要查询以下所有内容以确定当前值、最差值、阈值、驱动器状态和属性状态:
有关详细说明所有相关SMART HDD信息的C#/PHP综合解决方案,请参阅此解决方案http://www.know24.net/blog/C+WMI+HDD+SMART+Information.aspx(请注意:我拥有此开发博客)
更新2023-10-24
GitHub:https://github.com/krugertech/Krugertech.IO.Smart
Nuget:https://www.nuget.org/packages/Krugertech.IO.Smart
请随意捐款。