DyadyaGenya
Знающий
- Сообщения
- 300
- Репутация
- 10
Доброго времени суток. Продолжаю мучать смарт диска. Что-то получается. Но столкнулся с очередной проблемой. Захотел сделать проверку на соответствие буквы диска диску, чтобы получать инфу по смарту в зависимости от буквы диска. Сама проверка работает. Создаю массив, в котором в одной строке буква и номер диска (название, идентификатор, вендор). В варианте без такой сортировки, только с массивом из списка вендоров, все работает, показывает смарт только тех дисков, которые имеют смарт (без учета nvme). В варианте с проверкой на букву диска происходит что-то типа сдвига на одну позицию, или возможно добавление позиции из промежуточного массива, где есть все диски, в том числе и те, у которых смарт не читается, например флэшки. И получается выводит инфу на один диск (букву) меньше.
Вот первый вариант без сортировки по буквам:
Вот вариант с сортировкой по буквам:
Есть ещё один вариант проверки. Так сказать промежуточный. В нем чуток другой механизм проверки, и он не доделан. В нем в ручном режиме добавляется признак смарта от вендора (дописывается в конце "_0"). Зато в этом варианте работает более менее, как я хочу. Только там где диск не поддерживает смарт, напр, флэшка, просто показывает пустой массив. Но, к сожалению этот вариант не помещается. Присоединю чуть позже в сообщении, если нужно будет
Оставил кучу закомментированных строк, где проверял вывод промежуточных результатов.
Хотелось бы получать смарт по букве диска
Добавил ещё один отчет для проверки и оказалось, что не зависимо от того, подключены NVME и флэшка или нет, все равно не выводит смарт первого диска. Вот что выводит в консоли моего второго варианта в шапке темы:
Решил проблему ) Оказалось, что накладываются результаты команды
Разделил на $objWMIServiceCIMV2 и $objWMIServiceWMI и все заработало )
Вот первый вариант без сортировки по буквам:
Код:
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUITab.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>
#include <String.au3>
#include <Array.au3>
#include <Math.au3>
;Opt("MustDeclareVars", 1)
Global $sSMARTCodeTxt = "1*1*Raw Read Error Rate*Частота ошибок при чтении данных с диска;" & _
"2*2*Throughput Performance*Общая производительность диска.;" & _
"3*3*Spin-Up Time*Время раскрутки пакета дисков из состояния покоя до рабочей скорости.;" & _
"4*4*Start/Stop Count*Полное число циклов запуск-остановка шпинделя. В поле raw value хранится общее количество запусков/остановок диска;" & _
"5*5*Reallocated Sectors Count*Число операций переназначения секторов.;" & _
"6*6*Read Channel Margin*Запас канала чтения. Назначение этого атрибута не документировано. В современных накопителях не используется.;" & _
"7*7*Seek Error Rate*Частота ошибок при позиционировании блока магнитных головок.;" & _
"8*8*Seek Time Performance*Средняя производительность операции позиционирования магнитными головками.;" & _
"194*C2*HDA temperature*Температура. Здесь хранятся показания встроенного термодатчика для механической части диска — банки (HDA — Hard Disk Assembly).;" & _
"254*FE*Free Fall Protection*Защита от падения"
Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Global $Index[0], $Smart[0][12]
Global $aArray = DriveGetDrive("ALL")
Global $sTemp, $sTemp231, $sTemp1, $i, $j, $p, $sPark, $Item[0]
Global $strVendorSpecific[0], $strVendorSpecificA[0], $Specific[0][12], $diskVendors[0][2], $Threshold[0], $ThresholdAll[0], $Threshold[0], $Porog[0]
Global $STR1[0][4]
$TTT = _StringExplode($sSMARTCodeTxt, ";")
ConsoleWrite('TTT ' & UBound($TTT) & @CR)
;_ArrayDisplay($TTT, 'TTT')
For $s = 0 To UBound($TTT)-1
_ArrayAdd($STR1, $TTT[$s], 0, "*")
Next
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $diskVendor In $colItems
ConsoleWrite ("InstanceName: " & $diskVendor.InstanceName&@CR)
ConsoleWrite ("InstanceNameFor: " & StringReplace($diskVendor.InstanceName, '\','\\') &@CR)
;ConsoleWrite(Ubound($diskVendor) & @CR)
_ArrayAdd($diskVendors, $diskVendor.InstanceName &'|'&StringReplace($diskVendor.InstanceName, '\','\\'))
Next
_ArrayDisplay($diskVendors, 'массив вендоров')
ConsoleWrite('STR1 ' & UBound($STR1) & @CR)
For $zzzzz=0 To UBound($diskVendors)-1
ConsoleWrite('Число вендоров ' & UBound($diskVendors)-1 & @CR)
ConsoleWrite('Перед вызовом функции ' & $diskVendors[$zzzzz][1] & @CR)
_Smart($diskVendors[$zzzzz][1])
Next
Func _Smart($zzz)
ConsoleWrite('Уже в функции ' & $diskVendors[$zzzzz][1] & @CR)
$colThreshold = $objWMIService.ExecQuery('SELECT * FROM MSStorageDriver_FailurePredictThresholds Where InstanceName="' & $zzz &'"', "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $objThreshold In $colThreshold
$VendorSpecific2 = $objThreshold.VendorSpecific
_arrayDisplay($VendorSpecific2,"$VendorSpecific2")
; ConsoleWrite ("FailurePredictThresholds: " & _ArrayToString($VendorSpecific2,",")&@CR)
Next
If IsObj($objThreshold) then
For $zV = 2 to UBound($VendorSpecific2) - 1 Step 12
_ArrayAdd($ThresholdAll, $VendorSpecific2[$zV])
Next
; _ArrayDisplay($ThresholdAll, 'Порог')
For $j = 0 To UBound($STR1)-1
For $zzV = 2 to UBound($VendorSpecific2) - 1 Step 12
Select
Case $VendorSpecific2[$zzV]=$STR1[$j][0]
$Porog=$VendorSpecific2[$zzV+1]
If StringStripWS($Porog, 8) <> '' Then _ArrayAdd($Threshold, $Porog)
; ConsoleWrite($Porog)
EndSelect
Next
Next
For $t = 0 To 30-UBound($Threshold)
_ArrayAdd($Threshold, '0')
Next
; _ArrayDisplay($Threshold, 'Porog')
EndIf
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery('SELECT * FROM MSStorageDriver_ATAPISmartData Where InstanceName="' & $zzz &'"', "WQL", 0x30)
For $Item In $colItems
$strVendorSpecific = $Item.VendorSpecific
; _ArrayDisplay($strVendorSpecific,"Спецификация")
Next
For $z = 2 to UBound($strVendorSpecific) - 1 Step 12
$strSpecific = $strVendorSpecific[$z] & '|' & $strVendorSpecific[$z+1] & '|' & $strVendorSpecific[$z+2] & '|' & $strVendorSpecific[$z+3] & '|' & $strVendorSpecific[$z+4] & '|' & $strVendorSpecific[$z+5] & '|' & $strVendorSpecific[$z+6] & '|' & $strVendorSpecific[$z+7] & '|' & $strVendorSpecific[$z+8] & '|' & $strVendorSpecific[$z+9] & '|' & $strVendorSpecific[$z+10] & '|' & $strVendorSpecific[$z+11]
; _ArrayAdd($kzz, $strVendorSpecific[$z])
_ArrayAdd($Specific, $strSpecific)
Next
; _ArrayDisplay($Specific, "массив спецификаций", Default, '', Default, "ID|2|3|4|5|6|7|8|9|10|11|12")
Local $ks= UBound($STR1)-1
For $j = 0 To UBound($Specific)-1
For $k = 0 To UBound($STR1)-1
If Mod($Specific[$j][1],2) Then
$p = 'Pre-Failure'
Else
$p = 'Advisory'
EndIf
Local $raw = ((((($Specific[$j][8] * 256 ) + $Specific[$j][7]) * 256) + $Specific[$j][6]) * 256) + $Specific[$j][5]
Select
Case $Specific[$j][0]=$STR1[$k][0]
$sPark = $Specific[$j][0]& '|' & $STR1[$k][1]& '|' & $STR1[$k][2] & '|' & $p & '|' & $Specific[$j][1] & '|' & $Threshold[$j] & '|' & $Specific[$j][3] & '|' & $Specific[$j][4] & '|' & $Specific[$j][5] & '|' & $Specific[$j][6] & '|' & $raw
If StringStripWS($sPark, 8) <> 0 Then _ArrayAdd($Smart, $sPark)
Case $Specific[$j][0] <> $STR1[$k][0] And $k <> Mod($k, $ks) And $j <> UBound($Smart)-1
$sPark = $Specific[$j][0]& '|' & '???' & '|' & 'Зарезервировано производителем' & '|' & $p & '|' & $Specific[$j][1] & '|' & $Threshold[$j] & '|' & $Specific[$j][3] & '|' & $Specific[$j][4] & '|' & $Specific[$j][5] & '|' & $Specific[$j][6] & '|' & $raw
If StringStripWS($sPark, 8) <> 0 Then _ArrayAdd($Smart, $sPark)
Case Else
$sPark=''
; ConsoleWrite('else ' & $sPark & @CR)
EndSelect
Next
;ConsoleWrite('aaaa ' & $sPark & @CR)
Next
;_ArrayDisplay($Smart, "Smart")
_ArrayDisplay($Smart, 'Smart', Default, '', Default, "ID|HEX|Attribute|Type|Flag|Threshold(Порог)|Текущее|Worst(Наихудший)|Значение|???|RAW|Status")
Global $Smart[0][12]
;Global $STR1[0][4]
Global $Specific[0][12]
EndFunc
Код:
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUITab.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>
#include <String.au3>
#include <Array.au3>
#include <Math.au3>
Global $sSMARTCodeTxt = "1*1*Raw Read Error Rate*Частота ошибок при чтении данных с диска;" & _
"2*2*Throughput Performance*Общая производительность диска.;" & _
"3*3*Spin-Up Time*Время раскрутки пакета дисков из состояния покоя до рабочей скорости.;" & _
"4*4*Start/Stop Count*Полное число циклов запуск-остановка шпинделя. В поле raw value хранится общее количество запусков/остановок диска;" & _
"5*5*Reallocated Sectors Count*Число операций переназначения секторов.;" & _
"6*6*Read Channel Margin*Запас канала чтения. Назначение этого атрибута не документировано. В современных накопителях не используется.;" & _
"7*7*Seek Error Rate*Частота ошибок при позиционировании блока магнитных головок.;" & _
"8*8*Seek Time Performance*Средняя производительность операции позиционирования магнитными головками.;" & _
"194*C2*HDA temperature*Температура. Здесь хранятся показания встроенного термодатчика для механической части диска — банки (HDA — Hard Disk Assembly).;" & _
"254*FE*Free Fall Protection*Защита от падения"
Const $wbemFlagReturnImmediately = 0x10
Const $wbemFlagForwardOnly = 0x20
Global $Index[0], $Smart[0][12]
Global $aArray = DriveGetDrive("ALL")
Global $sTemp, $sTemp231, $sTemp1, $i, $j, $p, $sPark, $Item[0]
Global $strVendorSpecific[0], $strVendorSpecificA[0], $Specific[0][12], $diskVendors[0][2], $Threshold[0], $ThresholdAll[0], $Threshold[0], $Porog[0]
Global $STR1[0][4]
Global $DiskLeter[0][4]
Global $DiskPartArray[0], $DiskVendorArray[0], $deviceArray[0]
Global $DiskLeter[0][4], $LetterVendor[0][5]
$TTT = _StringExplode($sSMARTCodeTxt, ";")
ConsoleWrite('TTT ' & UBound($TTT) & @CR)
;_ArrayDisplay($TTT, 'TTT')
For $s = 0 To UBound($TTT)-1
_ArrayAdd($STR1, $TTT[$s], 0, "*")
Next
;Начало проблемного кода.
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItemsVendor = $objWMIService.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $diskVendor In $colItemsVendor
ConsoleWrite($diskVendor.InstanceName & @CR)
$disk = $diskVendor.InstanceName
_ArrayAdd($DiskVendorArray, $disk)
Next
_ArrayDisplay($DiskVendorArray, 'массив вендоров')
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
$colDiskDrives = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive")
For $objDrive In $colDiskDrives
ConsoleWrite(@CR & "Физический диск: " & $objDrive.Caption & " — " & $objDrive.DeviceID & @CR)
;ConsoleWrite("буква диска: " & $objDrive.Caption & " — " & $objDrive.DeviceID & @CR)
$strDeviceID = StringReplace($objDrive.DeviceID, "\", "\\")
ConsoleWrite('dev id ' & $strDeviceID & @CR)
$colPartitions = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & $strDeviceID & """} WHERE AssocClass = " & "Win32_DiskDriveToDiskPartition")
ConsoleWrite('проверка $colPartitions ' & $colPartitions & ' aaa' & @CR)
For $objPartition In $colPartitions
ConsoleWrite("Диск Partition: " & $objPartition.DeviceID & @CR)
; ConsoleWrite('айди: ' & $objDrive.PNPDeviceID &@CR)
$colLogicalDisks = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & $objPartition.DeviceID & """} WHERE AssocClass = " & "Win32_LogicalDiskToPartition")
For $objLogicalDisk In $colLogicalDisks
ConsoleWrite("Logical Disk: " & $objLogicalDisk.DeviceID & " Disk Partition: " & $objPartition.DeviceID & ' ' & $objDrive.PNPDeviceID & ' ' & StringReplace($objDrive.PNPDeviceID, '\','\\') & ' ' & @CR)
$Leter = $objLogicalDisk.DeviceID & '|' & $objPartition.DeviceID & '|' & $objDrive.PNPDeviceID & '|' & StringReplace($objDrive.PNPDeviceID, '\','\\')
_ArrayAdd($DiskLeter, $Leter)
Next
; ConsoleWrite($objLogicalDisk & @CR)
Next
;ConsoleWrite($objLogicalDisk & @CR)
Next
_ArrayDisplay($DiskLeter, 'Буквы диска', Default, '', Default, "1|2|3|4")
For $ds = 0 To UBound($DiskVendorArray)-1
For $dd = 0 To UBound($DiskLeter)-1
If StringLeft($DiskVendorArray[$ds],StringLen($DiskLeter[$dd][2])) = String($DiskLeter[$dd][2]) then
ConsoleWrite('ravno ' & $DiskLeter[$dd][2] & @CR)
$ravno = $DiskLeter[$dd][0] & '|' & $DiskLeter[$dd][1] & '|' & $DiskLeter[$dd][2] & '|' & $DiskVendorArray[$ds] & '|' & StringReplace($DiskVendorArray[$ds], '\','\\')
_ArrayAdd($LetterVendor, $ravno)
Else
ConsoleWrite('ne ravno ' & $DiskVendorArray[$ds] & ' <> ' & $DiskLeter[$dd][2] &@CR)
EndIf
Next
Next
_ArrayDisplay($LetterVendor, 'Буквы vendor', Default, '', Default, "1|2|3|4|5")
ConsoleWrite('STR1 ' & UBound($STR1) & @CR)
;Вызов функции, в которой происходит сбой
For $zzzzz=0 To UBound($LetterVendor)-1
ConsoleWrite('Перед вызовом функции смарт ' & $LetterVendor[$zzzzz][4] & @CR)
_Smart($LetterVendor[$zzzzz][4])
Next
Func _Smart($zzz)
; ConsoleWrite($diskVendors[$zzzzz][1] & @CR)
ConsoleWrite('уже в функции: ' & $zzz & @CR)
$colThreshold = $objWMIService.ExecQuery('SELECT * FROM MSStorageDriver_FailurePredictThresholds Where InstanceName="' & $zzz &'"', "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $objThreshold In $colThreshold
$VendorSpecific2 = $objThreshold.VendorSpecific
_arrayDisplay($VendorSpecific2,"$VendorSpecific2")
ConsoleWrite ("FailurePredictThresholds: " & _ArrayToString($VendorSpecific2,",")&@CR)
Next
If IsObj($objThreshold) then
For $zV = 2 to UBound($VendorSpecific2) - 1 Step 12
_ArrayAdd($ThresholdAll, $VendorSpecific2[$zV])
Next
_ArrayDisplay($ThresholdAll, 'Порог')
For $j = 0 To UBound($STR1)-1
For $zzV = 2 to UBound($VendorSpecific2) - 1 Step 12
Select
Case $VendorSpecific2[$zzV]=$STR1[$j][0]
$Porog=$VendorSpecific2[$zzV+1]
If StringStripWS($Porog, 8) <> '' Then _ArrayAdd($Threshold, $Porog)
; ConsoleWrite($Porog)
EndSelect
Next
Next
For $t = 0 To 30-UBound($Threshold)
_ArrayAdd($Threshold, '0')
Next
; _ArrayDisplay($Threshold, 'Porog')
EndIf
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
$colItems = $objWMIService.ExecQuery('SELECT * FROM MSStorageDriver_ATAPISmartData Where InstanceName="' & $zzz &'"', "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
For $Item In $colItems
$strVendorSpecific = $Item.VendorSpecific
; _ArrayDisplay($strVendorSpecific,"Спецификация")
Next
For $z = 2 to UBound($strVendorSpecific) - 1 Step 12
$strSpecific = $strVendorSpecific[$z] & '|' & $strVendorSpecific[$z+1] & '|' & $strVendorSpecific[$z+2] & '|' & $strVendorSpecific[$z+3] & '|' & $strVendorSpecific[$z+4] & '|' & $strVendorSpecific[$z+5] & '|' & $strVendorSpecific[$z+6] & '|' & $strVendorSpecific[$z+7] & '|' & $strVendorSpecific[$z+8] & '|' & $strVendorSpecific[$z+9] & '|' & $strVendorSpecific[$z+10] & '|' & $strVendorSpecific[$z+11]
_ArrayAdd($Specific, $strSpecific)
Next
; _ArrayDisplay($Specific, "массив спецификаций", Default, '', Default, "ID|2|3|4|5|6|7|8|9|10|11|12")
Local $ks= UBound($STR1)-1
If UBound($Threshold)>1 Then
For $j = 0 To UBound($Specific)-1
For $k = 0 To UBound($STR1)-1
If Mod($Specific[$j][1],2) Then
$p = 'Pre-Failure'
Else
$p = 'Advisory'
EndIf
Local $raw = ((((($Specific[$j][8] * 256 ) + $Specific[$j][7]) * 256) + $Specific[$j][6]) * 256) + $Specific[$j][5]
Select
Case $Specific[$j][0]=$STR1[$k][0]
$sPark = $Specific[$j][0]& '|' & $STR1[$k][1]& '|' & $STR1[$k][2] & '|' & $p & '|' & $Specific[$j][1] & '|' & $Threshold[$j] & '|' & $Specific[$j][3] & '|' & $Specific[$j][4] & '|' & $Specific[$j][5] & '|' & $Specific[$j][6] & '|' & $raw
If StringStripWS($sPark, 8) <> 0 Then _ArrayAdd($Smart, $sPark)
Case $Specific[$j][0] <> $STR1[$k][0] And $k <> Mod($k, $ks) And $j <> UBound($Smart)-1
$sPark = $Specific[$j][0]& '|' & '???' & '|' & 'Зарезервировано производителем' & '|' & $p & '|' & $Specific[$j][1] & '|' & $Threshold[$j] & '|' & $Specific[$j][3] & '|' & $Specific[$j][4] & '|' & $Specific[$j][5] & '|' & $Specific[$j][6] & '|' & $raw
If StringStripWS($sPark, 8) <> 0 Then _ArrayAdd($Smart, $sPark)
Case Else
$sPark=''
EndSelect
Next
Next
EndIf
_ArrayDisplay($Smart, 'Smart', Default, '', Default, "ID|HEX|Attribute|Type|Flag|Threshold(Порог)|Текущее|Worst(Наихудший)|Значение|???|RAW|Status")
Global $Smart[0][12]
Global $Specific[0][12]
EndFunc
Оставил кучу закомментированных строк, где проверял вывод промежуточных результатов.
Хотелось бы получать смарт по букве диска
Сообщение автоматически объединено:
Добавил ещё один отчет для проверки и оказалось, что не зависимо от того, подключены NVME и флэшка или нет, все равно не выводит смарт первого диска. Вот что выводит в консоли моего второго варианта в шапке темы:
Код:
Перед вызовом функции смарт E: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
уже в функции: E: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
Перед вызовом функции смарт I: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
уже в функции: I: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
FailurePredictThresholds: ; Тут длинный отчет, с данными смарта, его длина не пропускается форумом
Перед вызовом функции смарт H: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
уже в функции: H: SCSI\\Disk&Ven_Hitach_&Prod_HDS721050CLA362\\4&1f5e0e69&0&020000_0
FailurePredictThresholds: ; Тут длинный отчет, с данными смарта, его длина не пропускается форумом
Перед вызовом функции смарт J: SCSI\\Disk&Ven_LITEON&Prod_CV3-DE256\\4&1f5e0e69&0&030000_0
уже в функции: J: SCSI\\Disk&Ven_LITEON&Prod_CV3-DE256\\4&1f5e0e69&0&030000_0
FailurePredictThresholds: ; Тут длинный отчет, с данными смарта, его длина не пропускается форумом
Перед вызовом функции смарт C: SCSI\\Disk&Ven_ST310003&Prod_33AS\\4&1f5e0e69&0&040000_0
уже в функции: C: SCSI\\Disk&Ven_ST310003&Prod_33AS\\4&1f5e0e69&0&040000_0
FailurePredictThresholds: ; Тут длинный отчет, с данными смарта, его длина не пропускается форумом
Перед вызовом функции смарт D: SCSI\\Disk&Ven_ST310003&Prod_33AS\\4&1f5e0e69&0&040000_0
уже в функции: D: SCSI\\Disk&Ven_ST310003&Prod_33AS\\4&1f5e0e69&0&040000_0
FailurePredictThresholds: ; Тут длинный отчет, с данными смарта, его длина не пропускается форумом
Сообщение автоматически объединено:
Решил проблему ) Оказалось, что накладываются результаты команды
Код:
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\WMI")
и
$objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
Разделил на $objWMIServiceCIMV2 и $objWMIServiceWMI и все заработало )
Последнее редактирование: