Travaillant actuellement sur un projet d'optimisation HDD/SSD, cela a nécessité de récupérer les informations SMART d'un disque dur de type SSD ou HDD en s'appuyant sur les objets WMI :
Voilà à quoi pourrait ressembler une telle librairie avec l'espace de nom "Smart" (en c#) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
namespace Smart
{
public class Infos
{
public byte[] VendorSpecByte { get; set; }
public string InstanceN { get; set; }
public List Datas { get; set; }
public Infos()
{
Datas = new List();
LoadInfos();
}
private void LoadInfos()
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI", "SELECT VendorSpecific, InstanceName FROM MSStorageDriver_FailurePredictData"))
{
foreach (ManagementObject data in searcher.Get())
{
try
{
this.VendorSpecByte = (byte[])data.GetPropertyValue("VendorSpecific");
this.InstanceN = (string)data.GetPropertyValue("InstanceName");
for (int i = 0; i <= 29; i++)
{
int id = VendorSpecByte[i * 12 + 2];
int flags = VendorSpecByte[i * 12 + 4];
bool failureImminent = (flags & 0x1) == 0x1;
UInt32 vendordata = BitConverter.ToUInt32(VendorSpecByte, i * 12 + 7);
if (!(id == 0))
{
PropertyContent pInfos = new PropertyContent();
pInfos.Id = id;
pInfos.Value = Convert.ToString(vendordata);
pInfos.IsOk = (failureImminent == false);
this.Datas.Add(pInfos);
}
}
}
catch (ManagementException ex)
{
throw new ManagementException("Erreur WMI", ex);
}
}
}
}
public string FormatToString()
{
string str = String.Empty;
foreach (PropertyContent d in Datas)
{
str += ("ID:"
+ (d.Id + ("\r\n" + ("PropertyName:"
+ (d.PropertyName + ("\r\n" + ("PropertyValue:"
+ (d.Value + ("\r\n" + ("PropertyState:"
+ (Convert.ToString(d.IsOk) + "\r\n")))))))))));
}
return str;
}
}
public class PropertyContent
{
private int m_Id;
public int Id
{
get { return m_Id; }
set
{
m_Id = value;
switch (m_Id)
{
case 1:
m_PropertyName = PropertyNames.RawReadErrorRate;
break;
case 2:
m_PropertyName = PropertyNames.ThroughputPerformance;
break;
case 3:
m_PropertyName = PropertyNames.SpinUpTime;
break;
case 4:
m_PropertyName = PropertyNames.StartStopCount;
break;
case 5:
m_PropertyName = PropertyNames.ReallocatedSectorCount;
break;
case 6:
m_PropertyName = PropertyNames.ReadChannelMargin;
break;
case 7:
m_PropertyName = PropertyNames.SeekErrorRate;
break;
case 8:
m_PropertyName = PropertyNames.SeekTimePerformance;
break;
case 9:
m_PropertyName = PropertyNames.PowerOnHours;
break;
case 10:
m_PropertyName = PropertyNames.SpinRetryCount;
break;
case 11:
m_PropertyName = PropertyNames.CalibrationRetryCount;
break;
case 12:
m_PropertyName = PropertyNames.PowerCycleCount;
break;
case 171:
m_PropertyName = PropertyNames.ProgramFailBlockCount;
break;
case 172:
m_PropertyName = PropertyNames.EraseFailBlockCount;
break;
case 173:
m_PropertyName = PropertyNames.UnknownAttribute;
break;
case 174:
m_PropertyName = PropertyNames.UnexpectedPowerLossCount;
break;
case 187:
m_PropertyName = PropertyNames.ReportedUncorrectableErrors;
break;
case 192:
m_PropertyName = PropertyNames.PoweroffRetractCount;
break;
case 193:
m_PropertyName = PropertyNames.LoadCycleCount;
break;
case 194:
m_PropertyName = PropertyNames.Temperature;
break;
case 196:
m_PropertyName = PropertyNames.ReallocationEventCount;
break;
case 197:
m_PropertyName = PropertyNames.CurrentPendingSectorCount;
break;
case 198:
m_PropertyName = PropertyNames.OfflineScanUncorrectableSectorCount;
break;
case 199:
m_PropertyName = PropertyNames.UltraDMACRCErrorCount;
break;
case 201:
m_PropertyName = PropertyNames.SoftReadErrorRate;
break;
case 220:
m_PropertyName = PropertyNames.DiskShift;
break;
case 230:
m_PropertyName = PropertyNames.LifeCurveStatus;
break;
case 232:
m_PropertyName = PropertyNames.AvailableReservedSpace;
break;
case 234:
m_PropertyName = PropertyNames.Reserved;
break;
case 241:
m_PropertyName = PropertyNames.LifetimeWritesFromHost;
break;
case 242:
m_PropertyName = PropertyNames.LifetimeReadsFromHost;
break;
}
}
}
private string m_PropertyName;
public string PropertyName
{
get { return m_PropertyName; }
}
public string Value { get; set; }
public bool IsOk { get; set; }
private struct PropertyNames
{
public const string RawReadErrorRate = "Raw Read Error Rate";
public const string ThroughputPerformance = "Throughput Performance";
public const string SpinUpTime = "Spin Up Time";
public const string StartStopCount = "Start/Stop Count";
public const string ReallocatedSectorCount = "Reallocated Sector Count";
public const string ReadChannelMargin = "Read Channel Margin";
public const string SeekErrorRate = "Seek Error Rate";
public const string SeekTimePerformance = "Seek Time Performance";
public const string PowerOnHours = "Power-On Hours";
public const string SpinRetryCount = "Spin Retry Count";
public const string CalibrationRetryCount = "Calibration Retry Count";
public const string PowerCycleCount = "Power Cycle Count";
public const string ProgramFailBlockCount = "Program Fail Block Count";
public const string EraseFailBlockCount = "Erase Fail Block Count";
public const string UnknownAttribute = "Unknown Attribute";
public const string UnexpectedPowerLossCount = "Unexpected Power Loss Count";
public const string ReportedUncorrectableErrors = "Reported Uncorrectable Errors";
public const string PoweroffRetractCount = "Power-off Retract Count";
public const string LoadCycleCount = "Load Cycle Count";
public const string Temperature = "Temperature";
public const string ReallocationEventCount = "Reallocation Event Count";
public const string CurrentPendingSectorCount = "Current Pending Sector Count";
public const string OfflineScanUncorrectableSectorCount = "Off-line Scan Uncorrectable Sector Count";
public const string UltraDMACRCErrorCount = "Ultra DMA CRC Error Count";
public const string SoftReadErrorRate = "Soft Read Error Rate";
public const string DiskShift = "Disk Shift";
public const string LifeCurveStatus = "Life Curve Status";
public const string AvailableReservedSpace = "Available Reserved Space";
public const string Reserved = "Reserved";
public const string LifetimeWritesFromHost = "Lifetime Writes From Host";
public const string LifetimeReadsFromHost = "Lifetime Reads From Host";
}
}
}
J'ai volontairement créer une méthode ToString afin de pouvoir deboguer le rendu :
SmartInfos infos = new Smart.Infos();
MessageBox.Show(Convert.ToString(infos));
PS : Je me suis inspiré de ce billet pour obtenir les données de retour :
SMART
Bon codage à tous.