Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Программы » AutoIT (Часть 2)

Модерирует : gyra, Maz

Widok (01-06-2010 13:08): Лимит страниц. Продолжаем здесь.  Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

   

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
   

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Программы » AutoIT (Часть 2)
Widok (01-06-2010 13:08): Лимит страниц. Продолжаем здесь.


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru