- Сообщения
- 5,379
- Репутация
- 2,724
На досуге написал пару функций для работы с реестром. Обе используют рекурсивные вызовы и требуют наличие библиотеки WinAPIEx.au3.
_RegEnumValues() - создает список всех разделов со своими переменными, их значениями и всеми подразделами любой вложенности для указанного раздела реестра. Другими словами, создает структуру раздела реестра. Функция возвращает строку, разделителем в которой является символ с кодом 160 (Unicode) - ChrW(160). Каждая запись в этой строке имеет следующий вид:
относительный путь к разделу\\параметр=(тип)значение
Если параметр имеет строковое значение, то добавляются кавычки:
относительный путь к разделу\\параметр=(тип)"значение"
Каждый раздел начинается с его пути и заканчивается символом "\":
относительный путь к разделу\
Пример для раздела "HKEY_CLASSES_ROOT\.txt":
Для чего это нужно? Ну во-первых, вы получаете сразу структуру всего раздела за относительно небольшое время. Во-вторых, это очень удобно для сравнения двух разделов реестра на идентичность.
Замечание. Если к какому-нибудь разделу реестра в пределах заданной ветки будет отказано в доступе на чтение, то функция завершится с ошибкой.
Код:
_RegEnumTimes() - возвращает уникальный идентификатор, основанный на времени последней модификации указанного раздела реестра и всех его подразделов любой вложенности. Если вы измените что-нибудь в указанном разделе или в любом из его подразделов и т.д., то значение, возвращаемое этой функцией изменится. Эта функция на порядок быстрее _RegEnumValues(). Смысловой нагрузки значение идентификатора никакой не несет, важен лишь факт его изменения. Это очень удобно для отслеживания факта изменения раздела реестра.
Так же, как и в предыдущей функции, _RegEnumTimes() завершится с ошибкой при отказе в доступе на чтение к любому подразделу указанного раздела реестра.
Код:
Жду отзывов.
_RegEnumValues() - создает список всех разделов со своими переменными, их значениями и всеми подразделами любой вложенности для указанного раздела реестра. Другими словами, создает структуру раздела реестра. Функция возвращает строку, разделителем в которой является символ с кодом 160 (Unicode) - ChrW(160). Каждая запись в этой строке имеет следующий вид:
относительный путь к разделу\\параметр=(тип)значение
Если параметр имеет строковое значение, то добавляются кавычки:
относительный путь к разделу\\параметр=(тип)"значение"
Каждый раздел начинается с его пути и заканчивается символом "\":
относительный путь к разделу\
Пример для раздела "HKEY_CLASSES_ROOT\.txt":
Код:
@=(1)"txtfile"
PerceivedType=(1)"text"
Content Type=(1)"text/plain"
Mac Comment=(1)"ASCII File (SimpleText)"
Mac Type=(1)"TEXT"
Mac Creator=(1)"ttxt"
PersistentHandler\
PersistentHandler\\@=(1)"{5e941d80-bf96-11cd-b579-08002b30bfeb}"
ShellNew\
ShellNew\\NullFile=(1)""
Для чего это нужно? Ну во-первых, вы получаете сразу структуру всего раздела за относительно небольшое время. Во-вторых, это очень удобно для сравнения двух разделов реестра на идентичность.
Замечание. Если к какому-нибудь разделу реестра в пределах заданной ветки будет отказано в доступе на чтение, то функция завершится с ошибкой.
Код:
Код:
#Include <Array.au3>
#Include <Constants.au3>
#Include <WinAPIEx.au3>
;~Global Const $REG_BINARY = 3
;~Global Const $REG_DWORD = 4
;~Global Const $REG_DWORD_BIG_ENDIAN = 5
;~Global Const $REG_DWORD_LITTLE_ENDIAN = 4
;~Global Const $REG_EXPAND_SZ = 2
;~Global Const $REG_LINK = 6
;~Global Const $REG_MULTI_SZ = 7
;~Global Const $REG_NONE = 0
Global Const $REG_QWORD = 11
;~Global Const $REG_QWORD_LITTLE_ENDIAN = 11
;~Global Const $REG_SZ = 1
Global $hKey, $Hive
$hKey = _WinAPI_RegOpenKey($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
_RegEnumValues($hKey, $Hive)
_WinAPI_RegCloseKey($hKey)
$Hive = StringSplit($Hive, ChrW(160))
_ArrayDisplay($Hive)
Func _RegEnumValues($hRoot, ByRef $sData, $iLevel = -1, $iLenght = 0, $iParam = 0, $sParam = 0)
If (($iLevel > -1) And ($iParam > $iLevel)) Or (($iLenght) And (StringLen($sData) > $iLenght)) Then
Return SetError(1, -1, 0)
EndIf
If Not $iParam Then
$sData = ''
EndIf
$iParam += 1
Local $hKey, $sKey, $aKey, $sVal, $aText, $sText, $Quotes, $Size, $Struct, $Type, $Sep = ChrW(160), $Error = 0
Local $tData = DllStructCreate('byte[1048576]')
Local $pData = DllStructGetPtr($tData)
If $sParam Then
$sData &= $sParam & '\' & $Sep
EndIf
$aKey = _WinAPI_RegQueryInfoKey($hRoot)
If @error Then
Return SetError(1, @extended, 0)
EndIf
For $i = 0 To $aKey[2] - 1
$sVal = _WinAPI_RegEnumValue($hRoot, $i)
If @error Then
Return SetError(1, @extended, 0)
EndIf
$Size = _WinAPI_RegQueryValue($hRoot, $sVal, $tData)
If @error Then
Return SetError(1, @extended, 0)
EndIf
$Type = @extended
If Not $sVal Then
$sVal = '@'
EndIf
If Not $Size Then
$sText = ''
Else
Switch $Type
Case $REG_MULTI_SZ
$sText = ''
$aText = _WinAPI_StructToArray($pData)
If @error Then
Return SetError(1, -1, 0)
EndIf
For $j = 1 To $aText[0] - 1
$sText &= $aText[$j] & @LF
Next
If $aText[0] Then
$sText &= $aText[$aText[0]]
EndIf
$Quotes = 1
Case Else
$Quotes = 0
Switch $Type
Case $REG_DWORD, $REG_DWORD_BIG_ENDIAN
$Struct = 'dword'
Case $REG_QWORD
$Struct = 'uint64'
Case $REG_SZ, $REG_EXPAND_SZ
$Struct = 'wchar[' & $Size & ']'
$Quotes = 1
Case Else
$Struct = 'byte[' & $Size & ']'
EndSwitch
$sText = DllStructGetData(DllStructCreate($Struct, $pData), 1)
If $Quotes Then
$sText = '"' & $sText & '"'
EndIf
EndSwitch
EndIf
If $sParam Then
$sData &= $sParam & '\\'
EndIf
$sData &= $sVal & '=(' & $Type & ')' & $sText & $Sep
Next
For $i = 0 To $aKey[0] - 1
$sKey = _WinAPI_RegEnumKey($hRoot, $i)
If @error Then
Return SetError(1, @extended, 0)
EndIf
$hKey = _WinAPI_RegOpenKey($hRoot, $sKey, $KEY_READ)
If @error Then
Return SetError(1, @extended, 0)
EndIf
If $sParam Then
_RegEnumValues($hKey, $sData, $iLevel, $iLenght, $iParam, $sParam & '\' & $sKey)
Else
_RegEnumValues($hKey, $sData, $iLevel, $iLenght, $iParam, $sKey)
EndIf
If @error Then
$Error = @extended
If Not $Error Then
$Error = -1
EndIf
EndIf
_WinAPI_RegCloseKey($hKey)
If $Error Then
ExitLoop
EndIf
Next
If $iParam = 1 Then
If Not $Error Then
$sData = StringRegExpReplace($sData, $Sep & '*\Z', '')
Else
$sData = ''
EndIf
EndIf
Return SetError($Error <> 0, $Error, $Error = 0)
EndFunc ;==>_RegEnumValues
_RegEnumTimes() - возвращает уникальный идентификатор, основанный на времени последней модификации указанного раздела реестра и всех его подразделов любой вложенности. Если вы измените что-нибудь в указанном разделе или в любом из его подразделов и т.д., то значение, возвращаемое этой функцией изменится. Эта функция на порядок быстрее _RegEnumValues(). Смысловой нагрузки значение идентификатора никакой не несет, важен лишь факт его изменения. Это очень удобно для отслеживания факта изменения раздела реестра.
Так же, как и в предыдущей функции, _RegEnumTimes() завершится с ошибкой при отказе в доступе на чтение к любому подразделу указанного раздела реестра.
Код:
Код:
#Include <Crypt.au3>
#Include <WinAPIEx.au3>
Global $hKey, $ID
$hKey = _WinAPI_RegOpenKey($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
_RegEnumTimes($hKey, $ID)
_WinAPI_RegCloseKey($hKey)
ConsoleWrite($ID & @CR)
Func _RegEnumTimes($hRoot, ByRef $sData, $iParam = 0)
If Not $iParam Then
$sData = ''
EndIf
$iParam += 1
Local $hKey, $sKey, $aKey, $tTime, $Error = 0
$tTime = _WinAPI_RegQueryLastWriteTime($hRoot)
If @error Then
Return SetError(1, @extended, 0)
EndIf
For $i = 1 To 2
$sData &= DllStructGetData($tTime, $i)
Next
$aKey = _WinAPI_RegQueryInfoKey($hRoot)
If @error Then
Return SetError(1, @extended, 0)
EndIf
For $i = 0 To $aKey[0] - 1
$sKey = _WinAPI_RegEnumKey($hRoot, $i)
If @error Then
Return SetError(1, @extended, 0)
EndIf
$hKey = _WinAPI_RegOpenKey($hRoot, $sKey, $KEY_READ)
If @error Then
Return SetError(1, @extended, 0)
EndIf
_RegEnumTimes($hKey, $sData, $iParam)
If @error Then
$Error = @extended
If Not $Error Then
$Error = -1
EndIf
EndIf
_WinAPI_RegCloseKey($hKey)
If $Error Then
ExitLoop
EndIf
Next
If $iParam = 1 Then
If Not $Error Then
$sData = StringTrimLeft(_Crypt_HashData($sData, $CALG_MD5), 2)
Else
$sData = ''
EndIf
EndIf
Return SetError($Error <> 0, $Error, $Error = 0)
EndFunc ;==>_RegEnumTimes
Жду отзывов.