저는 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
이해가 안되는 것은) Value 다음의 바이트를 변수 다음에 asign하여 변수에 저장하는 법입니다. "public struct SmartAttribute"에 있어야한다고 생각합니다 ... – user1120389