Advertisement
AZJIO

reg-backup

Aug 6th, 2012
1,158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 11.05 KB | None | 0 0
  1. #include <_RegFunc.au3> ; http://www.autoitscript.com/forum/topic/70108-custom-registry-functions-udf/
  2. #include <Array.au3>
  3.  
  4. ;  @AZJIO 2012.08
  5. ; Этот скрипт позволяет сделать экспотрт разделов реестра, параметры которого будут изменены в результате слияния REG-файла.
  6. ; Спасибо Spiff59 за оптимизацию поиска уникальных разделов, Erik Pilsits за _RegFunc.
  7.  
  8. ; En
  9. $LngCM = 'Backup reg'
  10. $LngSel1 = 'Select'
  11. $LngSel2 = 'REG-File'
  12. $LngPr1 = '1. Search for unique , 0 %'
  13. $LngPr2 = '%,  Key:'
  14. $LngS = 'sec'
  15. $LngPr3 = '2. Export, 0 %,  Key:'
  16. $LngPr4 = '2. Export,'
  17. ; $LngErr1 = 'Key:"'
  18. ; $LngErr2 = '" Valuename:"'
  19. ; $LngErr3 = '" type:"'
  20. ; $LngErr4 = '" Value:"'
  21.  
  22. ; Ru
  23. ; если русский, то использовать его
  24. If @OSLang = 0419 Then
  25.     $LngCM = 'Резервирование reg-данных'
  26.     $LngSel1 = 'Выбор файла, данные которого резервируются.'
  27.     $LngSel2 = 'REG-файл'
  28.     $LngPr1 = '1. Поиск уникальных, 0 %'
  29.     $LngPr2 = '%, раздел:'
  30.     $LngS = 'сек'
  31.     $LngPr3 = '2. Экспорт из реестра, 0 %,  разделов:'
  32.     $LngPr4 = '2. Экспорт из реестра,'
  33.     ; $LngErr1 = 'ключ:"'
  34.     ; $LngErr2 = '" параметр:"'
  35.     ; $LngErr3 = '" тип:"'
  36.     ; $LngErr4 = '" значение:"'
  37. EndIf
  38.  
  39. ; входные параметры скрипта
  40. $Author_Date = '@AZJIO 2012.08'
  41. ; $sHeader = 'REGEDIT4' ; для win98
  42. $sHeader = 'Windows Registry Editor Version 5.00'
  43. $iTrDel = 1 ; ключ 1 - создавать файл удаления веток, 0 - не создавать
  44. Global $Data = '', $sKey, $DataErr = '', $Re = '', $sKey = '', $sValuename, $sValue, $sValuetype, $L, $hex
  45.  
  46. ; Добавление в реестр
  47. RegRead("HKCR\regfile\shell\mbackup", '')
  48. If @error = 1 Then
  49.     ;регистрация в реестре и копирование в системную папку, при первом запуске
  50.     RegWrite("HKCR\regfile\shell\mbackup", "", "REG_SZ", $LngCM)
  51.     RegWrite("HKCR\regfile\shell\mbackup\command", "", "REG_SZ", @AutoItExe & ' "' & @SystemDir & '\reg-backup.au3" "%1"')
  52.     If Not FileExists(@SystemDir & '\reg-backup.au3') Then FileCopy(@ScriptFullPath, @SystemDir, 1)
  53. EndIf
  54.  
  55. ;Добавление $sTarget позволило использовать скрипт в контекстном меню
  56. If $CmdLine[0] Then
  57.     $sPathReg = $CmdLine[1]
  58. Else
  59.     $sPathReg = FileOpenDialog($LngSel1, @ScriptDir & "", $LngSel2 & " (*.reg)", 1 + 4)
  60.     If @error Then Exit
  61. EndIf
  62.  
  63. $aPath = StringRegExp($sPathReg, "^(.*)\\(.*)\.(.*)$", 3) ; массив: путь, имя и расширение
  64.  
  65. $timer0 = TimerInit() ; засекаем время
  66. ; генерируем имя нового файла с номером копии на случай если файл существует
  67. $iNFile = 1
  68. While FileExists($aPath[0] & '\' & $aPath[1] & '_BAK' & $iNFile & '.reg') Or FileExists($aPath[0] & '\' & $aPath[1] & '_DEL' & $iNFile & '.reg')
  69.     $iNFile += 1
  70. WEnd
  71.  
  72. ;оболочка сообщений о ходе процесса если reg-файл 100кб и более
  73. ProgressOn($LngCM, $aPath[1] & '.reg', $LngPr1 & @CRLF & @CRLF & @Tab & @Tab & @Tab & $Author_Date, -1, -1, 18)
  74.  
  75. $sRegData = FileRead($sPathReg) ; открываем бэкапируемый файл для чтения
  76.  
  77. ; удаление пустых секций
  78. $sRegData = StringTrimRight(StringRegExpReplace($sRegData & "[", "\[[^\]]*\]\s*(?=\[)", ""), 1)
  79. ;$sRegData=StringRegExpReplace($sRegData,"(\[.*\])(?=(\s+\[.*|\s+$|$))","")
  80. $sRegData = StringReplace($sRegData, "]", "\")
  81. $aRegKey = StringRegExp($sRegData, "(?m)^(\[HK.*\\)(?:\r$|\z)", 3) ; создание массива веток реестра
  82. If @error Then Exit ; если файл пустой, то выход
  83. _ArraySort($aRegKey, 0) ; сортировать по убыванию
  84.  
  85. $n = UBound($aRegKey)
  86. $i = 0
  87. For $j = 1 to $n-1
  88.     If Not StringInStr($aRegKey[$j], $aRegKey[$i]) Then
  89.         $i += 1
  90.         $aRegKey[$i] = $aRegKey[$j]
  91.     Endif
  92. Next
  93. ReDim $aRegKey[$i + 1]
  94. $n = $i
  95.  
  96. $timer0 = Round(TimerDiff($timer0) / 1000)
  97.  
  98. ProgressSet(0, $LngPr3 & ' ' & $i+1 & @CRLF & @CRLF & @Tab & @Tab & @Tab & $Author_Date)
  99. $timer1 = TimerInit() ; засекаем время для учёта времени создания экспорта
  100. $Data = ''
  101. $z = 1
  102.  
  103. $sRegDel = ''
  104. ; _ArrayDisplay($aRegKey, 'Array')
  105. ; Exit
  106. For $i = 0 To $n
  107.     $sKey = StringRegExpReplace($aRegKey[$i], '^\[|\\$', "") ; удаление скобок в строке, дабы секция стала веткой
  108.     If $iTrDel Then $sRegDel &= '[-' & $sKey & ']' & @CRLF ; запись строки в reg-файл удаления
  109.     If _RegKeyExists($sKey) Then ; если существует, то
  110.         _RegExport_X($sKey, $Data) ; экспорт указанного раздела реестра в переменную $Data
  111.         ; статистика: рассчёт полосы прогресса
  112.         $ps = Round(($i+1) * 100 / ($n+1))
  113.         ProgressSet($ps, $LngPr4 & ' ' & $ps & ' ' & $LngPr2 & ' ' & $i+1 & ' / ' & $n & @CRLF & _
  114.         $timer0 & ' + ' & Round(TimerDiff($timer1) / 1000) & ' ' & $LngS & @CRLF & @Tab & @Tab & @Tab & $Author_Date)
  115.     EndIf
  116. Next
  117. ProgressOff()
  118.  
  119. If $Data Or $DataErr Then ; пишем в файл, если данные получены
  120.     $hFile = FileOpen($aPath[0] & '\' & $aPath[1] & '_BAK' & $iNFile & '.reg', 2)
  121.     FileWrite($hFile, $sHeader & @CRLF & $Data & @CRLF & $DataErr & @CRLF)
  122.     FileClose($hFile)
  123. EndIf
  124.  
  125. If $iTrDel And $sRegDel Then; пишем в файл, если разделы есть и ключ $iTrDel включен
  126.     $hFile = FileOpen($aPath[0] & '\' & $aPath[1] & '_DEL' & $iNFile & '.reg', 2)
  127.     FileWrite($hFile, '#' & $sHeader & @CRLF & @CRLF & $sRegDel)
  128.     FileClose($hFile)
  129. EndIf
  130.  
  131.  
  132. Func _RegExport_X($sKey, ByRef $Data)
  133.     Local $aaaValue, $asValue0, $cmd, $DataErr, $hex, $i, $L, $line1, $Re, $sTemp, $sValue, $sValue0, $sValuename, $sValuetype
  134.  
  135.     $i = 0
  136.     Do
  137.         $i += 1
  138.         ; If $i=1 Then $Data &= @CRLF & '[' & $sKey & ']' & @CRLF
  139.         $sValuename = RegEnumVal($sKey, $i)
  140.         If @error Then ExitLoop
  141.         $sValue = _RegRead($sKey, $sValuename, True)
  142.         If @error Then ContinueLoop
  143.         $sValuetype = @extended
  144.         ; $sValueName = StringRegExpReplace($sValueName, '[\\]', "\\$0") ; всегда заменяем в параметре наклонную черту на двойную
  145.         $sValuename = StringReplace($sValuename, '\', "\\") ; всегда заменяем в параметре наклонную черту на двойную
  146.         If $i = 1 Then $Data &= @CRLF & '[' & $sKey & ']' & @CRLF ; если строку переместить к началу, то все разделы даже пустые добавятся
  147.         ; здесь для каждого типа данных свой алгоритм извлечения значений
  148.         Switch $sValuetype
  149.             Case 1
  150.                 $sValue = StringReplace(StringReplace(StringRegExpReplace($sValue, '["\\]', "\\$0"), '=\"\"', '="\"'), '\"\"', '\""')
  151.                 $Data &= '"' & $sValuename & '"="' & $sValue & '"' & @CRLF
  152.             Case 7, 2
  153.                 $hex = _HEX($sValuetype, $sValue, $sValuename, $L)
  154.                 $Data &= '"' & $sValuename & '"=' & $L & $hex & @CRLF
  155.             Case 4
  156.                 $Data &= '"' & $sValuename & '"=dword:' & StringLower(Hex(Int($sValue))) & @CRLF
  157.             Case 3
  158.                 $hex = _HEX(3, $sValue, $sValuename, $L)
  159.                 $Data &= '"' & $sValuename & '"=' & $L & $hex & @CRLF
  160.             Case 0, 8, 9, 10, 11 ; тип данных которые не распознаёт AutoIt3, поэтому используется экспорт консольной командой.
  161.                 ; Вытаскиваем значение в консоль и читаем с неё
  162.                 $hex = _HEX($sValuetype, $sValue, $sValuename, $L)
  163.                 $Data &= '"' & $sValuename & '"=' & $L & $hex & @CRLF
  164.             Case Else
  165.                 $DataErr &= '# error... Key:"' & $sKey & '" Valuename:"' & $sValuename & '" Value:"' & $sValue & '" type:"' & $sValuetype & '"' & @CRLF
  166.         EndSwitch
  167.     Until 0
  168.     ;рекурсия
  169.     $i = 0
  170.     While 1
  171.         $i += 1
  172.         $sTemp = RegEnumKey($sKey, $i)
  173.         If @error Then ExitLoop
  174.         $DataErr &= _RegExport_X($sKey & '\' & $sTemp, $Data)
  175.     WEnd
  176.     $Data = StringReplace($Data, '""=', '@=') ; заменяем в данных параметры по умолчанию на правильные
  177.     Return $DataErr
  178. EndFunc
  179.  
  180. ; функция шестнадцатеричных данных, основное её значение - привести запись к формату reg-файла (перенос строк)
  181. ; данные подгонялись методом сравнения оригинального экспорта и reg-файлом полученным скриптом до полного совпадения.
  182. Func _HEX($sValuetype, ByRef $sValue, $sValuename, ByRef $L)
  183.     Local $aValue, $hex, $i, $k, $len, $lenVN, $r, $s, $s0
  184.     $k = 0
  185.     $lenVN = StringLen($sValuename) - 1
  186.     Switch $sValuetype
  187.         Case 0
  188.             $L = 'hex(0):'
  189.         Case 3
  190.             $k = 1
  191.             $L = 'hex:'
  192.         Case 2
  193.             $k = 1
  194.             $L = 'hex(2):'
  195.             $sValue = StringToBinary($sValue, 2)
  196.             $sValue &= '0000'
  197.             $lenVN = StringLen($sValuename) + 2
  198.         Case 7
  199.             $k = 1
  200.             $L = 'hex(7):'
  201.             ; $sValue = StringToBinary($sValue, 2) ; строковый в бинарный вид
  202.             ; $sValue = StringReplace($sValue, '000a00', '000000') ; по какой то причине экспортированные и прочитанные данные разнятся этими блоками
  203.             ; $sValue &= '00000000' ; шестнадцатеричные данные заполнены окончания нулями, иногда не совпадает количество, автоит обрезает так как читает данные как текстовые
  204.         Case 8
  205.             $sValue = StringTrimLeft($sValue, 2)
  206.             $L = 'hex(8):'
  207.         Case 10
  208.             $L = 'hex(a):'
  209.         Case 11
  210.             $L = 'hex(b):'
  211.         Case 9
  212.             ; $k = -1
  213.             $sValue = StringTrimLeft($sValue, 2)
  214.             $L = 'hex(9):'
  215.     EndSwitch
  216.     $hex = ''
  217.     $aValue = StringRegExp($sValue, '..', 3)
  218.     $len = UBound($aValue) ; от колич. символов параметра зависит колич. бинарных данных первой строки
  219.     If $lenVN >= 69 Then $lenVN = 66
  220.     $s0 = 22 - ($lenVN - Mod($lenVN, 3)) / 3 ; количество символов для первой строки reg-данных
  221.     Switch $sValuetype
  222.         Case 7, 8, 9
  223.             $s0 -= 1
  224.     EndSwitch
  225.     $s = 0
  226.     $r = 0
  227.     For $i = $k To $len - 1 ; цикл формирует правильный перенос строк, и разделительные запятые
  228.         If $s = $s0 Or $r = 24 Then
  229.             $hex &= $aValue[$i] & ',\' & @CRLF & '  '
  230.             $s = 24
  231.             $r = 0
  232.         Else
  233.             $hex &= $aValue[$i] & ','
  234.             $s += 1
  235.             $r += 1
  236.         EndIf
  237.     Next
  238.     $hex = StringTrimRight($hex, 1)
  239.     If StringRight($hex, 5) = ',\' & @CRLF & ' ' Then $hex = StringTrimRight($hex, 5) ;обрезка конца значания
  240.     $hex = StringLower($hex) ; преобразование в строчные
  241.     Return $hex
  242. EndFunc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement