AZJIO
Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Скрипт бэкапирует ветки текущего реестра считывая их из reg-файла. В отличии от предыдущего варианта, в котором используется многократный экспорт во временный файл и добавление из него к общему файлу, в новом скрипте происходит чтение параметров без экспорта. По скорости операции новый чаще читает быстрее, особенно когда много веток и в каждой мало параметров. Старый выигрывает когда в reg-файле мало веток, но в каждой ветке много подветок и соответственно параметров. Старый читает равномерно ~10 веток в сек. Скорость нового равномерно по параметрам, а по веткам колеблется от 50 веток в сек до одной ветки в 5 сек. Код: ; @AZJIO 18.04.2010 ; основные параметры скрипта $tempfile=@TempDir&'\temporarily.reg' $razdelit='' ; разделяет экспортированные ветки, количество тоже, что веток в файле удаления $del=1 ;ключ 1 - создавать файл удаления веток, 0 - не создавать Global $Data='', $temporarily, $DataErr='', $Re='', $sKey='', $sValuename, $sValue, $sValuetype,$L,$hex $close = RegRead("HKCR\regfile\shell\mbackup", '') If @error=1 Then ;регистрация в реестре и копирование в системную папку, при первом запуске RegWrite("HKCR\regfile\shell\mbackup","","REG_SZ","Бэкапировать reg") RegWrite("HKCR\regfile\shell\mbackup\command","","REG_SZ",@AutoItExe&' "'&@SystemDir&'\reg-backup.au3" "%1"') If Not FileExists(@SystemDir&'\reg-backup.au3') Then FileCopy(@ScriptDir&'\reg-backup.au3', @SystemDir,1) EndIf ;Добавление $sTarget позволило использовать скрипт в контекстном меню If $CmdLine[0]=0 Then $regfile = FileOpenDialog("Выбор файла *.reg, для которого будет выполнен бэкап.", @ScriptDir & "", "reg-файл (*.reg)", 1 + 4 ) If @error Then Exit Else $regfile=$CmdLine[1] EndIf $aRegfileS = StringRegExp($regfile, "(^.*)\\(.*)$", 3) ; чтобы указать каталог reg-файла для выходных файлов $aRegfileS1 = StringRegExp($regfile, "(^.*)\\(.*)\.(.*)$", 3) $timer = TimerInit() ; засекаем время ; генерируем имя нового файла с номером копии на случай если файл существует $i = 1 While FileExists($aRegfileS1[1]&'_BAK'&$i&'.reg') or FileExists($aRegfileS1[1]&'_DEL'&$i&'.reg') $i +=1 WEnd $filename=$aRegfileS1[1]&'_BAK'&$i&'.reg' $delname=$aRegfileS1[1]&'_DEL'&$i&'.reg' If $del=1 Then $delfile = FileOpen($aRegfileS[0]&'\'&$delname, 1) FileWrite($delfile, '#Windows Registry Editor Version 5.00'&@CRLF&@CRLF) EndIf ;оболочка сообщений о ходе процесса если reg-файл 100кб и более ProgressOn("Бэкапирование", $aRegfileS[1], "1. Очистка подветок, 0 %"&@CRLF&@CRLF&" @AZJIO 18.04.2010",-1,-1,18) $regfileT = FileOpen($regfile, 0) ; открываем бэкапируемый файл для чтения $regfileT1= FileRead($regfileT) FileClose($regfileT) ; удаление пустых секций $regfileT1=StringTrimRight (StringRegExpReplace($regfileT1 & "[","\[[^\]]*\]\s*(?=\[)",""),1) ;$regfileT1=StringRegExpReplace($regfileT1,"(\[.*\])(?=(\s+\[.*|\s+$|$))","") $aRegfileT1 = StringRegExp($regfileT1, "(\[HK.*?\])", 3) ; создание массива веток реестра $regfileT1='' For $i = 0 to UBound($aRegfileT1) - 1 ; объединение массива в многостроковый файл $regfileT1&=$aRegfileT1[$i]&@CRLF Next $iaReg=UBound($aRegfileT1) - 1 ; чистка подветок, пустых строк, повторов. Файл 1Мб обрабатывается до минуты в этом цикле. ; в тексте удаляется каждый элемент массива и добавляется в конец строки ; Регулярным выражением подготавливается поисковой шаблон, заменяются спец-символы на обрамляющий слеш For $i = 0 to $iaReg $regfileT1=StringRegExpReplace($regfileT1,StringRegExpReplace(StringTrimRight($aRegfileT1[$i], 1), "[][{}()*+?.\\^$|=<>#]", "\\$0")&'(\\.*|\])',"") If @Extended >0 Then $regfileT1 &= @CRLF&$aRegfileT1[$i] $ps=Ceiling ($i*100/$iaReg) ProgressSet( $ps, "1. Очистка подветок, 0 %"&$ps & " %, ветка: "&$i&' / '&$iaReg&@CRLF&Ceiling(TimerDiff($timer) / 1000) & " сек"&@CRLF&" @AZJIO 18.04.2010") Next $timer0=Ceiling(TimerDiff($timer) / 1000) $regfileT1=StringRegExpReplace($regfileT1,'\n\r?\n\r?',"") ;удаление пустых строк $aRecords = StringSplit($regfileT1, @CRLF) ; отправляем в массив построчно ProgressSet( 0, "2. Экспорт из реестра, 0 %, ветка: "&$i&@CRLF&@CRLF&" @AZJIO 19.03.2010") $timer1 = TimerInit() ; засекаем время для учёта времени создания экспорта $filebackup = FileOpen($aRegfileS[0]&'\'&$filename, 1) ; открываем бэкап-файл If $razdelit<>'' Then $razdelit&=@CRLF $Data='' $z=1 if IsInt($aRecords[0]/2) Then ; счётчик строк $a=$aRecords[0]/2 Else $a=($aRecords[0]-1)/2 EndIf For $i=1 To $aRecords[0] If StringLeft($aRecords[$i], 3)='[HK' Then ; условие проверки валидности строки в элементе массива $temporarily = StringRegExpReplace($aRecords[$i],'\[|\]',"") ; удаление скобок в строке, дабы секция стала веткой If $del=1 Then FileWrite($delfile, '[-'&$temporarily&']'&@CRLF) $reg1 = RegRead($temporarily, "") ; проверка существования ветки If @error=1 Then ContinueLoop Else RegReplace($temporarily) EndIf EndIf ; статистика: рассчёт полосы прогресса, проверка деления на 2, так как в массиве в 2 раза больше строк $ps=Ceiling ($i*100/$aRecords[0]) if IsInt($i/2) Then $z=$i/2 ProgressSet( $ps, "2. Экспорт из реестра, "&$ps & " %, ветка: "&$z&' / '&$a&@CRLF&$timer0&' + '&Ceiling(TimerDiff($timer1) / 1000) & " сек"&@CRLF&" @AZJIO 18.04.2010") Next ProgressOff() FileWrite($filebackup, 'Windows Registry Editor Version 5.00'&@CRLF&$Data&@CRLF&$DataErr&@CRLF) ;FileWrite($filebackup, 'REGEDIT4'&@CRLF&@CRLF&$Data) ; для win98 ; закрываем файлы If $del=1 Then FileClose($delfile) FileClose($filebackup) ;если файл пустой, то удаляем его. Добавляется четыре строки и пустой файл равен нескольким байтам. If FileGetSize($aRegfileS[0]&'\'&$filename)=40 Then FileDelete($aRegfileS[0]&'\'&$filename) If $del=1 Then If FileGetSize($aRegfileS[0]&'\'&$delname)=41 Then FileDelete($aRegfileS[0]&'\'&$delname) EndIf Func RegReplace($sKey) ;$sKey - исходная ветка Local $i, $sTemp $i = 0 While 1 $i += 1 $sValuename = RegEnumVal($sKey, $i) If @error Then ExitLoop $sValue = RegRead($sKey, $sValuename) If @error=1 or @error=-1 Then ContinueLoop $sValuetype = @extended ;здесь идет модификация реестра $sValuename=StringRegExpReplace($sValuename,'[\\]',"\\$0") ; всегда заменяем в параметре наклонную черту на двойную Switch $sValuetype Case 1 $sValue=StringRegExpReplace($sValue,'["\\]',"\\$0") $sValue=StringRegExpReplace($sValue,'=\\"\\"','="\\"') $sValue=StringRegExpReplace($sValue,'\\"\\"','\\""') If $Re=$sKey Then $Data&='"'&$sValuename&'"="'&$sValue&'"'&@CRLF Else $Data&=@CRLF&'['&$sKey&']'&@CRLF&'"'&$sValuename&'"="'&$sValue&'"'&@CRLF $Re=$sKey EndIf Case 7, 2 _HEX($sValuetype) If $Re=$sKey Then $Data&='"'&$sValuename&'"='&$L&$hex&@CRLF Else $Data&=@CRLF&'['&$sKey&']'&@CRLF&'"'&$sValuename&'"='&$L&$hex&@CRLF $Re=$sKey EndIf Case 4 If $Re=$sKey Then $Data&='"'&$sValuename&'"=dword:'&StringLower(Hex ( Int( $sValue )))&@CRLF Else $Data&=@CRLF&'['&$sKey&']'&@CRLF&'"'&$sValuename&'"=dword:'&StringLower(Hex ( Int( $sValue )))&@CRLF $Re=$sKey EndIf Case 3 _HEX(3) If $Re=$sKey Then $Data&='"'&$sValuename&'"='&$L&$hex&@CRLF Else $Data&=@CRLF&'['&$sKey&']'&@CRLF&'"'&$sValuename&'"='&$L&$hex&@CRLF $Re=$sKey EndIf Case 0, 8, 10, 11 ; тип данных которые не распознаёт AutoIt3, поэтому используется через экспорт. ; Вытаскиваем значение в консоль и читаем с неё $cmd = Run ( @Comspec&' /C reg query "'&$sKey&'" /v "'&$sValuename&'"', @SystemDir, @SW_HIDE, 6) $sValue0='' While 1 $line1 = StdoutRead($cmd) If @error Then ExitLoop $sValue0 &= $line1 Wend ;Разбиваем полученные данные на подстроки ;кусок кода из UDF File.au3 для разделения образца построчно в массив If StringInStr($sValue0, @LF) Then $asValue0 = StringSplit(StringStripCR($sValue0), @LF) ElseIf StringInStr($sValue0, @CR) Then ; @LF does not exist so split on the @CR $asValue0 = StringSplit($sValue0, @CR) Else ;; unable to split the file If StringLen($sValue0) Then Dim $asValue0[2] = [1, $sValue0] Else $DataErr&='# error... ключ:"'&$sKey&'" параметр:"'&$sValuename&'" тип:"'&$sValuetype&'"'&@CRLF ContinueLoop EndIf EndIf ; детектируем в пятой строке третий параметр $aaaValue = StringRegExp($asValue0[UBound($asValue0) - 3], "[^\s{2,}]\S*", 3) If UBound($aaaValue)<3 and $sValuetype=0 Then $L='hex(0):' $hex=@CRLF Else If UBound($asValue0)<8 or UBound($aaaValue)<3 Then ContinueLoop Else $sValue=$aaaValue[2] EndIf EndIf _HEX($sValuetype) If $Re=$sKey Then $Data&='"'&$sValuename&'"='&$L&$hex&@CRLF Else $Data&=@CRLF&'['&$sKey&']'&@CRLF&'"'&$sValuename&'"='&$L&$hex&@CRLF $Re=$sKey EndIf Case Else $DataErr&='# error... ключ:"'&$sKey&'" параметр:"'&$sValuename&'" значение:"'&$sValue&'" тип:"'&$sValuetype&'"'&@CRLF EndSwitch WEnd ;рекурсия $i = 0 While 1 $i += 1 $sTemp = RegEnumKey($sKey, $i) If @error Then ExitLoop RegReplace($sKey & '\' & $sTemp) WEnd $Data=StringReplace($Data, '""=', '@=') ; заменяем в данных параметры по умолчанию на правильные ; заменяем данные выплненные экспортом (Case 0, 8, 10, 11) $Data = StringReplace($Data, "Windows Registry Editor Version 5.00"&@CRLF&@CRLF, @CRLF&$razdelit) Return EndFunc ; функция шестнадцатеричных данных, основное её значение - привети запись к формату reg-файла (перенос строк) Func _HEX($sValuetype) $k=1 Switch $sValuetype Case 0 $L='hex(0):' Case 3 $k=3 $L='hex:' Case 2 $k=3 $L='hex(2):' $sValue=StringToBinary($sValue,2) ;$sValue=StringReplace ($sValue,'000a00','000000') $sValue&='0000' Case 7 $k=3 $L='hex(7):' $sValue=StringToBinary($sValue,2) $sValue=StringReplace ($sValue,'000a00','000000') $sValue&='00000000' Case 8 $L='hex(8):' Case 10 $L='hex(a):' Case 11 $L='hex(b):' EndSwitch $hex='' $len = StringLen($sValue) $lenVN = StringLen($sValuename)-1 If $sValuetype=2 Then $lenVN=StringLen($sValuename)+2 If $lenVN>=69 Then $lenVN=66 $s0=22-($lenVN-mod($lenVN, 3))/3 ; количество символов для первой строки reg-данных If $sValuetype=7 or $sValuetype=8 Then $s0=21-($lenVN-mod($lenVN, 3))/3 $s=0 $r=0 For $h = $k To $len Step 2 $hex2 = StringMid($sValue, $h, 2) If $s=$s0 or $r=24 Then $hex&=$hex2&',\'&@CRLF&' ' $s=24 $r=0 Else $hex&=$hex2&',' $s+=1 $r+=1 EndIf Next $hex = StringTrimRight($hex,1) If StringRight($hex, 5)=',\'&@CRLF&' ' Then $hex = StringTrimRight($hex,5) $hex = StringLower($hex) ; преобразование в строчные EndFunc |
| Всего записей: 4407 | Зарегистр. 03-05-2006 | Отправлено: 01:05 17-04-2010 | Исправлено: AZJIO, 12:52 18-04-2010 |
|