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

holgip5t  于 2023-11-21  发布在  Windows
关注(0)|答案(1)|浏览(179)

我知道一点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

ippsafx7

ippsafx71#

请注意,并非所有SMART HDD(不包括USB和NVME驱动器)信息都可以从单个查询中获得。
您需要查询以下所有内容以确定当前值、最差值、阈值、驱动器状态和属性状态:

  • Win32_Windows驱动器
  • MSSTRR Driver_FailurePredictStatus
  • MSSTRR Driver_FailurePredictData
  • MSSTRR Driver_FailurePredictError保持

有关详细说明所有相关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

请随意捐款。

相关问题