Суть проблемы: необходимо провести сохранение ветки HCR перед работой с реестром с возможностью последующего восстановления (на всякий пожарный случай).
Применил следующий код:
Итог - после перезагрузки системы выскакивает синий экран смерти с указанием на Registry Error.
PS WinXp SP3, библиотека WinApiEx версия 2.7, в системе установлен тяжелый софт (Photoshop, Lingvo, прочее)
Добавлено:
Применение другого скрипта для экспорта ветки HCR (от того же Yashied), после запуска полученного reg-файла приводит к появлению окна -уведомления (см. аттач), но синего экрана после ребута уже нет.
Такое ощущение, что требуется перед сохранением/восстановлением давать полный доступ к ветке (с рекурсией) на запись...
Код 2-ого скрипта:
Применил следующий код:
Код:
Func _SaveRegNew() ; бэкап ветки реестра
$hKey = _WinAPI_RegOpenKey($HKEY_CLASSES_ROOT, '')
_WinAPI_RegSaveKey($hKey, @HomeDrive & '\hcr.reg')
_WinAPI_RegCloseKey($hKey)
MsgBox(0, '', '"Ветка HKEY_CLASSES_ROOT успешна сохранена в hcr.reg', 3)
EndFunc
Func _RestoreRegNew() ; восстановление из бэкапа ветки реестра
$hKey = _WinAPI_RegCreateKey($HKEY_CLASSES_ROOT, '')
_WinAPI_RegRestoreKey($hKey, @HomeDrive & '\hcr.reg')
_WinAPI_RegCloseKey($hKey)
MsgBox(0, '', '"Ветка HKEY_CLASSES_ROOT успешно восстановлена из hcr.reg".', 3)
EndFunc
Итог - после перезагрузки системы выскакивает синий экран смерти с указанием на Registry Error.
PS WinXp SP3, библиотека WinApiEx версия 2.7, в системе установлен тяжелый софт (Photoshop, Lingvo, прочее)
Добавлено:
Сообщение автоматически объединено:
Применение другого скрипта для экспорта ветки HCR (от того же Yashied), после запуска полученного reg-файла приводит к появлению окна -уведомления (см. аттач), но синего экрана после ребута уже нет.
Такое ощущение, что требуется перед сохранением/восстановлением давать полный доступ к ветке (с рекурсией) на запись...
Код 2-ого скрипта:
Код:
#Include <Constants.au3>
#Include <WinAPIEx.au3>
$sReg = _RegExportEx('HKEY_CLASSES_ROOT', 'hcr.reg')
;~ If @error Then
;~ ConsoleWrite(_WinAPI_GetErrorMessage(@extended) & @CR)
;~ Else
;~ ConsoleWrite($sReg & @CR)
;~ EndIf
Func _RegExportEx($sKey, $sFile = '', $fAssurance = 0)
Local $aData = StringSplit(StringUpper($sKey), '\', 2)
Local $tData, $hRoot, $sRoot, $sReg = ''
Local $Error = 1
If Not IsArray($aData) Then
Return SetError(1, 0, '')
EndIf
Switch $aData[0]
Case 'HKEY_CLASSES_ROOT', 'HKEY_CURRENT_USER', 'HKEY_LOCAL_MACHINE', 'HKEY_USERS', 'HKEY_CURRENT_CONFIG'
$sRoot = $aData[0]
Case 'HKCR'
$sRoot = 'HKEY_CLASSES_ROOT'
Case 'HKCU'
$sRoot = 'HKEY_CURRENT_USER'
Case 'HKLM'
$sRoot = 'HKEY_LOCAL_MACHINE'
Case 'HKU'
$sRoot = 'HKEY_USERS'
Case 'HKCC'
$sRoot = 'HKEY_CURRENT_CONFIG'
Case Else
Return SetError(1, 0, '')
EndSwitch
$sKey = StringTrimLeft($sKey, StringLen($aData[0]) + 1)
Do
$hRoot = _WinAPI_RegOpenKey(Eval($sRoot), $sKey, BitOR($KEY_ENUMERATE_SUB_KEYS, $KEY_QUERY_VALUE))
If @error Then
ExitLoop
EndIf
$tData = DllStructCreate('byte[1048576]')
If Not _RegEnumProc($hRoot, StringRegExpReplace($sRoot & '\' & $sKey, '\\*\Z', ''), $fAssurance, $sReg, $tData) Then
ExitLoop
EndIf
$Error = 0
Until 1
If $Error Then
Switch @extended
Case 0
$Error = -1
Case Else
$Error = @extended
EndSwitch
EndIf
If $hRoot Then
_WinAPI_RegCloseKey($hRoot)
EndIf
If $Error Then
Return SetError(2, $Error, '')
EndIf
If $sFile Then
$hFile = FileOpen($sFile, 2 + 32)
If $hFile = -1 Then
Return SetError(3, 0, '')
EndIf
If Not FileWrite($hFile, 'Windows Registry Editor Version 5.00' & @CRLF & @CRLF & $sReg) Then
$Error = 1
EndIf
FileClose($hFile)
If $Error Then
Return SetError(3, 0, '')
EndIf
Return 1
EndIf
Return $sReg
EndFunc ;==>_RegExportEx
Func _RegEnumProc($hRoot, $sRoot, $fAssurance, ByRef $sData, ByRef $tData, $sParam = 0)
Local $hKey, $sKey, $sVal, $Pos, $Size, $Type
Local $pData = DllStructGetPtr($tData)
Local $Count = 0, $Error = 0
If $sParam Then
$sData &= @CRLF & '[' & $sRoot & '\' & $sParam & ']' & @CRLF
Else
$sData = '[' & $sRoot & ']' & @CRLF
EndIf
While 1
$sVal = _WinAPI_RegEnumValue($hRoot, $Count)
If @error Then
Switch @extended
Case 259 ; ERROR_NO_MORE_ITEMS
ExitLoop
Case Else
Return SetError(1, @extended, 0)
EndSwitch
EndIf
$Size = _WinAPI_RegQueryValue($hRoot, $sVal, $tData)
If @error Then
Return SetError(1, @extended, 0)
EndIf
$Type = @extended
If $sVal Then
$sVal = '"' & StringReplace(StringReplace($sVal, '\', '\\'), '"', '\"') & '"='
Else
$sVal = '@='
EndIf
If Not $Size Then
Switch $Type
Case 1 ; REG_SZ
$sVal &= '""'
Case Else
Switch $Type
Case 3 ; REG_BINARY
$sVal &= 'hex:'
Case Else
$sVal &= 'hex(' & StringLower(Hex($Type, 1)) & '):'
EndSwitch
EndSwitch
Else
Switch $Type
Case 1 ; REG_SZ
$sVal &= '"' & StringReplace(StringReplace(DllStructGetData(DllStructCreate('wchar[' & $Size & ']', $pData), 1), '\', '\\'), '"', '\"') & '"'
Case 4 ; REG_DWORD
$sVal &= 'dword:' & StringLower(Hex(Number(DllStructGetData(DllStructCreate('dword', $pData), 1))))
Case Else
Switch $Type
Case 3 ; REG_BINARY
$sVal &= 'hex:'
Case Else
$sVal &= 'hex(' & StringLower(Hex($Type, 1)) & '):'
EndSwitch
$sVal &= StringTrimRight(StringRegExpReplace(StringLower(StringTrimLeft(DllStructGetData(DllStructCreate('byte[' & $Size & ']', $pData), 1), 2)), '(.{2})', '\1,'), 1)
$Pos = StringInStr($sVal, ',', 0, 1, 77)
If $Pos Then
$sVal = StringLeft($sVal, $Pos) & '\' & @CRLF & ' ' & StringRegExpReplace(StringTrimLeft($sVal, $Pos), '(.{75})', '\1\\' & @CRLF & ' ')
EndIf
EndSwitch
EndIf
$sData &= $sVal & @CRLF
$Count += 1
WEnd
$Count = 0
While 1
$sKey = _WinAPI_RegEnumKey($hRoot, $Count)
If @error Then
Switch @extended
Case 259 ; ERROR_NO_MORE_ITEMS
ExitLoop
Case Else
Return SetError(1, @extended, 0)
EndSwitch
EndIf
$hKey = _WinAPI_RegOpenKey($hRoot, $sKey, BitOR($KEY_ENUMERATE_SUB_KEYS, $KEY_QUERY_VALUE))
If @error Then
If $fAssurance Then
Return SetError(1, @extended, 0)
EndIf
Else
If $sParam Then
_RegEnumProc($hKey, $sRoot, $fAssurance, $sData, $tData, $sParam & '\' & $sKey)
Else
_RegEnumProc($hKey, $sRoot, $fAssurance, $sData, $tData, $sKey)
EndIf
If @error Then
Switch @extended
Case 0
$Error = -1
Case Else
$Error = @extended
EndSwitch
EndIf
EndIf
If $hKey Then
_WinAPI_RegCloseKey($hKey)
EndIf
$Count += 1
If $Error Then
ExitLoop
EndIf
WEnd
If $Error Then
Return SetError(1, $Error, 0)
Else
Return 1
EndIf
EndFunc ;==>_RegEnumProc