private void Run() { var smartInfos = getSmartInfos(); if (previousSmartInfos == null || HDD.Compare(smartInfos, previousSmartInfos) == false) { callBack(smartInfos); } previousSmartInfos = smartInfos; Task.Delay(1000 * 120, cancellationToken.Token).ContinueWith((t) => Run(), cancellationToken.Token); }
public static Dictionary <int, HDD> getSmartInfos() { var dicDrives = new Dictionary <int, HDD>(); var wdSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); // extract model and interface information int iDriveIndex = 0; foreach (ManagementObject drive in wdSearcher.Get()) { var hdd = new HDD(); hdd.Model = drive["Model"].ToString().Trim(); hdd.Type = drive["InterfaceType"].ToString().Trim(); dicDrives.Add(iDriveIndex, hdd); iDriveIndex++; } var pmsearcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia"); // retrieve hdd serial number iDriveIndex = 0; foreach (ManagementObject drive in pmsearcher.Get()) { // because all physical media will be returned we need to exit // after the hard drives serial info is extracted if (iDriveIndex >= dicDrives.Count) { break; } dicDrives[iDriveIndex].Serial = drive["SerialNumber"] == null ? "None" : drive["SerialNumber"].ToString().Trim(); iDriveIndex++; } // get wmi access to hdd var searcher = new ManagementObjectSearcher("Select * from Win32_DiskDrive"); searcher.Scope = new ManagementScope(@"\root\wmi"); // check if SMART reports the drive is failing searcher.Query = new ObjectQuery("Select * from MSStorageDriver_FailurePredictStatus"); iDriveIndex = 0; foreach (ManagementObject drive in searcher.Get()) { dicDrives[iDriveIndex].IsOK = (bool)drive.Properties["PredictFailure"].Value == false; iDriveIndex++; } // retrive attribute flags, value worste and vendor data information searcher.Query = new ObjectQuery("Select * from MSStorageDriver_FailurePredictData"); iDriveIndex = 0; foreach (ManagementObject data in searcher.Get()) { Byte[] bytes = (Byte[])data.Properties["VendorSpecific"].Value; for (int i = 0; i < 30; ++i) { try { int id = bytes[i * 12 + 2]; int flags = bytes[i * 12 + 4]; // least significant status byte, +3 most significant byte, but not used so ignored. //bool advisory = (flags & 0x1) == 0x0; bool failureImminent = (flags & 0x1) == 0x1; //bool onlineDataCollection = (flags & 0x2) == 0x2; int value = bytes[i * 12 + 5]; int worst = bytes[i * 12 + 6]; int vendordata = BitConverter.ToInt32(bytes, i * 12 + 7); if (id == 0) { continue; } var attr = dicDrives[iDriveIndex].Attributes[id]; attr.Current = value; attr.Worst = worst; attr.Data = vendordata; attr.IsOK = failureImminent == false; } catch { // given key does not exist in attribute collection (attribute not in the dictionary of attributes) } } iDriveIndex++; } // retreive threshold values foreach attribute searcher.Query = new ObjectQuery("Select * from MSStorageDriver_FailurePredictThresholds"); iDriveIndex = 0; foreach (ManagementObject data in searcher.Get()) { Byte[] bytes = (Byte[])data.Properties["VendorSpecific"].Value; for (int i = 0; i < 30; ++i) { try { int id = bytes[i * 12 + 2]; int thresh = bytes[i * 12 + 3]; if (id == 0) { continue; } var attr = dicDrives[iDriveIndex].Attributes[id]; attr.Threshold = thresh; } catch { // given key does not exist in attribute collection (attribute not in the dictionary of attributes) } } iDriveIndex++; } return(dicDrives); }