Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » Регфайл, синтаксис.

Ответить
Настройки темы
Регфайл, синтаксис.

Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


Изменения
Автор: semiono
Дата: 23-06-2009
Думаю пора обсудить написание валидных регфайлов средствами AutoIt3.
Хочется объединить всё вместе, как некое знание и рассмотреть все встречающиеся особенности записи различных типов параметров.

Сразу же хочеться отметить различие реестров x86 и x64, и в то же время рег синтакс исключающий записи вида HKLM/HKCU и т.п.

Здесь могут быть полезными выключатели
Код: Выделить весь код
Switch @OSArch
    Case 'x86'
        $sRegKey = 'HKLM\Software\RegKey'
    Case 'x64'
        $sRegKey = 'HKLM\Software\Wow6432Node\RegKey'
EndSwitch
Запись в файл может определяться переменной как

Код: Выделить весь код
$sFileContent = _
    'Windows Registry Editor Version 5.00' & @CRLF & @CRLF & _
    '[' & $sRegKey & ']' & @CRLF & _
    '"ValueName"=' & $sSerialResult & & @CRLF & @CRLF
Но при этом нельзя забывать, что имя куста должно быть полное, например $sRegKey = "HKEY_LOCAL_MACHINE\...", здесь нельзя использовать HKLM\

Однако, большую сложность думаю представляет запись значений параметров в валидном виде для регфалов!

Например, все типы кроме REG_SZ и REG_DWORD имеют запись вида = hex(2):
Причём, понятно что REG_EXPAND_SZ содержит юникод, экспортирующийся в виде шеснадцетиричного кода разделённого запятыми в регфайл. Закрывается строка нуевым символом, то-есть двумя байтами нулей ',00,00' (впрочем это так же актуально и для multisz и для binary)
Несмотря на то, что строки могут быть размещены без переносов, и это работает, однако майкрософт придумала способ записи разделяемой слеш, для переноса строки. Это красиво и хотелось бы тоже этому следовать.

Длина строк в такой записи содержит 25 байт разделённых запятыми, строки начинается с двух пробелов и заканчивается слеш, если нужен перенос
Код: Выделить весь код
  61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,\
Однако первая строка имеет не постоянную длину относительно имени переменной.
Минимальная строка содержит 22 байта разделённых запятыми, и начинает убавляться на один байт при увеличении длины имени переменной на 4 символа.
Код: Выделить весь код
"1"=hex(2):61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,\
"12"=hex(2):61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,\
"123"=hex(2):61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,\
"1234"=hex(2):61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,00,61,\ < строка стала короче
Тоже самое по поводу dword, запись имеет свою особенность.
"zzz"=dword:0001e240

И другие (zero-lenth-binary-value)
"value1"=hex(0):

У меня просьба, сделайте свои предложения по поводу кода autoit, и быть может это соберёться в некий включаемый файлик?

Вопрос: можно ли получить юникод или бинарную не ascii строку в перменную и затем разделить все байты строки запятыми?
Ну и особое желание - это установить слеши по схеме регфайла, тоесть с расчётом длинны, длин и т.п.


Ещё проще вопрос, как записать запятую через каждые два символа, заранее неизвестной строки...
aa,bb,ab,ac,....

-------
Полезное сообщение


Отправлено: 20:17, 22-06-2009

 

Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


Молодцы! Приставить к награде пора! Я в восторге!

-------
Полезное сообщение


Отправлено: 19:52, 24-06-2009 | #21



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для proxy

Старожил


Сообщения: 460
Благодарности: 152

Профиль | Отправить PM | Цитировать


7 миллионов доллоров, semiono, 7 миллионов

+ еще обновление:
Цитата:
Можно считывать как отдельную величину, так и все имеющиеся величины в ключе.
Учтено: длина строки < 76, и @CRLF в конце.
Уже лучше расставляются слеши, вся разбивка на StringRegExpReplace. »
эть, не чем же заняться в свободное время ...

-------
Мысли-читатель сломался, может подробней расскажите?
А где исходный код? Или мы стихи обсуждаем?! )) Настройки темы > Решено ?


Последний раз редактировалось proxy, 24-06-2009 в 22:25.

Это сообщение посчитали полезным следующие участники:

Отправлено: 20:45, 24-06-2009 | #22


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


коль пошла такая пьянка, кину и свой вариант
Код: Выделить весь код
$hFile = FileOpen("C:\TEST\TEST.reg", 8+2)

_RegValSave($hFile, "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\USBSTOR","DisplayName|Start|ImagePath")
_RegValSave($hFile, "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion","DevicePath|ProgramFilesDir", 1)
_RegValSave($hFile, "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\0","ViewView2", 1)

Func _RegValSave($file, $key, $vals = "", $iAdd = 0)
    Local $val, $txt = ""
    If Not(IsArray($vals)) Then $vals = StringSplit($vals,",;|",2)
    For $i=0 To UBound($vals)-1
        $val = RegRead($key, $vals[$i])
        If @error Then ContinueLoop
        $txt &= _RegValFormat($vals[$i], $val, @extended) &@CRLF
    Next
    If $txt == "" Then Return SetError(1, 0, 0)

    If IsString($file) Then $file = FileOpen($file, 8+2)
    If $file = -1 Then Return SetError(2, 0, 0)
    If $iAdd =0 Then FileWrite($file,'Windows Registry Editor Version 5.00'&@CRLF)
    Return FileWrite($file, @CRLF&"["& $key &"]"&@CRLF& $txt)
EndFunc

Func _RegValFormat($sVal, $xData, $iType = 1)
    If $iType=1 Then Return '"'& $sVal &'"="'& $xData &'"' ; REG_SZ
    If $iType=4 Then Return '"'& $sVal &'"=dword:'& Hex(Int($xData),8) ; REG_DWORD

    Local $sLeft='"'& $sVal &'"=hex('& $iType &'):', $sData, $iData, $iWrap=80
    If $iType=2 Then $xData=StringToBinary($xData & Chr(0), 2) ; REG_EXPAND_SZ
    If $iType=3 Then $sLeft='"'& $sVal &'"=hex:' ; REG_BINARY
    If $iType=7 Then $xData=StringToBinary(StringRegExpReplace($xData &@LF,"[\n\r]+",Chr(0)) &Chr(0), 2) ; REG_MULTI_SZ
    If Not(IsBinary($xData)) Then $xData = Binary(StringRegExpReplace($xData,"^(?i:\s*0x)?((?:[[:xdigit:]]{2})+)$","0x\1"))
    $xData = StringTrimRight(StringRegExpReplace(Hex($xData),"(..)", "\1,"), 1)

    While StringLen($sLeft)+StringLen($xData)>$iWrap
        $iData = Int(($iWrap-StringLen($sLeft)-1)/3)*3
        $sData&= $sLeft & StringLeft($xData, $iData) &"\" &@CRLF
        $xData = StringMid($xData, $iData+1)
        $sLeft="  "
    WEnd
    Return $sData & $sLeft  & $xData
EndFunc
Цитата proxy:
эть, не чем же заняться в свободное время ... »
честно говоря, не пойму чем semiono не устроил батник
Это сообщение посчитали полезным следующие участники:

Отправлено: 09:21, 25-06-2009 | #23


Аватара для proxy

Старожил


Сообщения: 460
Благодарности: 152

Профиль | Отправить PM | Цитировать


Цитата amel27:
коль пошла такая пьянка, кину и свой вариант »
, и как всегда все жуууутко замудренно и за рег-экспанно )))

Цитата:
semiono, нормальные герои всегда идут в обход (c)


пора, semiono, тему завершать?

-------
Мысли-читатель сломался, может подробней расскажите?
А где исходный код? Или мы стихи обсуждаем?! )) Настройки темы > Решено ?


Отправлено: 10:35, 25-06-2009 | #24


Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


Завершение уже не зависит от моего решения
Однако я нажал. +1

-------
Полезное сообщение


Отправлено: 04:23, 26-06-2009 | #25


Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


Чтоб это доброе дело продолжалось, было б, зделать утиль regEx.exe которая читает ввод командой строки,
например, # regex /export HKLM\Microsoft\'Windows NT\.la -la-la' C:\'.my reg.reg' и делает это. ?

-------
Полезное сообщение


Отправлено: 21:26, 27-06-2009 | #26


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата semiono:
зделать утиль regEx.exe которая читает ввод командой строки »
сколько угодно, только тестируйте
Код: Выделить весь код
Global $KEY, $VAL, $ADD = False, $OUT=StringRegExpReplace(@ScriptFullPath,".[^.]+$", ".reg")

Global $aParms = StringRegexp($CmdLineRaw, '/(\w+)(?:[\s:]+(?:"([^"]+)"|([^\s/"]+)))?', 4)
If @error Then Exit -1 ; Ошибка: не указано ни одного параметра
For $aParm In $aParms
    If UBound($aParm)=2 Then Assign($aParm[1], True)
    If UBound($aParm)>2 Then Assign($aParm[1], $aParm[UBound($aParm)-1])
Next

Global $iMode=8+2
If $ADD Then $iMode = 1

If $VAL=="*" Then $VAL = _RegEnumVals($KEY)
_RegValSave($OUT, $KEY, $VAL, $iMode)
Exit @error ; ошибки выполнения _RegValSave()

; =============================================================================
; _RegEnumVals($key)
; -----------------------------------------------------------------------------
; Перечисление всех параметров заданного ключа реестра
; $key        : имя ключа реестра
;
; При успехе  : возвращает массив имен параметров со счетчиком
; При неудаче : возвращает пустой массив
; =============================================================================
Func _RegEnumVals($key)
    Local $aRes[1]=[-1],$sVal=0
    Do
        $aRes[0] +=1
        ReDim $aRes[$aRes[0]+1]
        $aRes[$aRes[0]] = $sVal
        $sVal = RegEnumVal($key, $aRes[0]+1)
    Until @error
    Return $aRes
EndFunc ; ==> _RegEnumVals

; =============================================================================
; _RegValSave($file, $key, [$vals, [, $mode]])
; -----------------------------------------------------------------------------
; Сохранение заданных параметров в REG-файл
;
; $file       : имя файла или хэндл
; $key        : имя ключа реестра
; $vals       : одно или несколько имен параметров, разделенных ",|;"
 ;             : или массив элементов со счетчиком
; $mode       : режим открытия файла (см. FileOpen)
;
; При успехе  : возвращает 1
;
; При неудаче : возвращает 0
;             :   @error=0, неверный режим открытия
;             :   @error=1, не обнаружено ни одного из заданных параметров
;             :   @error=2, ошибка открытия файла
; =============================================================================
Func _RegValSave($file, $key, $vals = "", $mode = 10)
    Local $dat, $txt = ""
    If Not(IsArray($vals)) Then $vals = StringSplit($vals,",;|")
    For $i=1 To $vals[0]
        $dat = RegRead($key, $vals[$i])
        If @error Then ContinueLoop
        $txt &= _RegValFormat($vals[$i], $dat, @extended) &@CRLF
    Next
    If $txt=="" Then Return SetError(1, 0, 0)
    If IsString($file) Then
        $file = FileOpen($file, $mode)
        If $file = -1 Then Return SetError(2, 0, 0)
        If BitAND($mode,2) Then FileWrite($file,'Windows Registry Editor Version 5.00'&@CRLF)
    EndIf
    $key = StringRegExpReplace($key, "^HKLM\\", "HKEY_LOCAL_MACHINE\\")
    $key = StringRegExpReplace($key, "^HKCU\\", "HKEY_CURRENT_USER\\")
    $key = StringRegExpReplace($key, "^HKCR\\", "HKEY_CLASSES_ROOT\\")
    $key = StringRegExpReplace($key, "^HKU\\" , "HKEY_USERS\\")
    $key = StringRegExpReplace($key, "^HKCC\\", "HKEY_CURRENT_CONFIG\\")

    Return FileWrite($file, @CRLF&"["& $key &"]"&@CRLF& $txt)
EndFunc ; ==> _RegValSave

; =============================================================================
; _RegValFormat($sVal, $xData[, $iType])
; -----------------------------------------------------------------------------
; Вывод значения параметра реестра в формате REG-файла
;
; $sVal   : имя параметра
; $xData  : значение параметра, поддерживаемые комбинации тип+значение:
;             $iType=1, $xData - текстовая строка
;             $iType=2, $xData - текстовая строка
;             $iType=3, $xData - HEX или бинарная строка
;             $iType=4, $xData - целое 32-х битное число
;             $iType=7, $xData - одна или несколько текстовых строк
;         : при несоответствии, параметр преобразуется к требуемому типу
; $iType  : тип параметра
;             $iType=1 - REG_SZ
;             $iType=2 - REG_EXPAND_SZ
;             $iType=3 - REG_BINARY
;             $iType=4 - REG_DWORD
;             $iType=7 - REG_MULTI_SZ
;         : все другие значения $iType форматируются как REG_BINARY
; =============================================================================
Func _RegValFormat($sVal, $xData, $iType = 1)
    Local $sData='"'& $sVal &'"=hex('& $iType &'):', $iWidth
    If $sVal=="" Then $sVal="@"

    If $iType=1 Then Return '"'& $sVal &'"="'& $xData &'"' ; REG_SZ
    If $iType=2 Then $xData=StringToBinary($xData & Chr(0), 2) ; REG_EXPAND_SZ
    If $iType=3 Then $sData='"'& $sVal &'"=hex:' ; REG_BINARY
    If $iType=4 Then Return '"'& $sVal &'"=dword:'& Hex(Int($xData),8) ; REG_DWORD
    If $iType=7 Then $xData=StringToBinary(StringRegExpReplace($xData &@LF,"[\n\r]+",Chr(0)) &Chr(0), 2) ; REG_MULTI_SZ

    If Not(IsBinary($xData)) Then $xData = Binary(StringRegExpReplace($xData,"^(?i:\s*0x)?((?:[[:xdigit:]]{2})+)$","0x\1"))
    $xData = StringTrimRight(StringRegExpReplace(Hex($xData),"(..)", "\1,"), 1)

    $iWidth = 80-StringLen($sData)
    While StringLen($xData) > $iWidth
        $sData&= StringLeft($xData, Int(($iWidth-1)/3)*3) &"\"&@CRLF&"  "
        $xData = StringTrimLeft ($xData, Int(($iWidth-1)/3)*3)
        $iWidth = 78
    WEnd
    Return $sData & $xData
EndFunc ; _RegValFormat
компилировать консольным приложением (RegSave), пример использования:
Код: Выделить весь код
@Echo Off

RegSave /OUT:C:\TEST\TEST.reg /KEY:HKLM\SYSTEM\CurrentControlSet\Services\USBSTOR /VAL:DisplayName,Start,ImagePath
RegSave /OUT:C:\TEST\TEST.reg /KEY:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion /VAL:DevicePath,ProgramFilesDir /ADD
RegSave /OUT:C:\TEST\TEST.reg /KEY:HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\0 /VAL:* /ADD

Последний раз редактировалось amel27, 30-06-2009 в 03:54. Причина: мелкая оптимизация

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:47, 29-06-2009 | #27


Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


****
Регистр букв я сам исправил! Надеюсь правильно
If $iType=4 Then Return '"'& $sVal &'"=dword:'& StringLower(Hex(Int($xData),8)) ; REG_DWORD
...
$xData = StringTrimRight(StringRegExpReplace(StringLower(Hex($xData)),"(..)", "\1,"), 1)

Добавил ещё один &@CRLF в конец reg-файла, чтоб как у M$ было идентично.

1. Нашёл и более серьёзную проблему!!!
В именах пробелы нельзя использовать!
Хорошо что /key: double-quoted поддерживается:
"HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager" ,
но c "Value Name" облом ???!!!

2. Где в скрипте добавить ConsoleWrite() чтобы Success... выводилось согласно логике?

-------
Полезное сообщение


Последний раз редактировалось semiono, 25-01-2010 в 03:01.


Отправлено: 19:55, 22-01-2010 | #28


Аватара для semiono

Ветеран


Сообщения: 836
Благодарности: 33

Профиль | Отправить PM | Цитировать


Оказывается наполовину работает! Вообщем такое срабатывает /val "New Value #1"
Проблемма возникает при перечислении: /val "New Value #1","New Value #2", даже если один из параметров не имеет пробелов.
Причём, точки /val: можно не указывать, как я заметил.
Ну и всякие трансцендентальные типы REG_DWORD_BIG_ENDIAN скрипт не пережёвывает, впрочем это хорошо.

хух! нашёл "недокументированные возможности", можно так вбивать:
/val "New Value #2,New Value #1" — это валидно для работы RegSave* скрипта!

---
(!) есть небольшое различие в hex(7): записи пустых параметров.
regedit.exe "ExcludeFromKnownDlls"=hex(7):00,00
regsave.exe "ExcludeFromKnownDlls"=hex(7):00,00,00,00

--- я добавил вывод в консоль, для приличия похоже, что логично работает...
Код: Выделить весь код
Global $aParms = StringRegexp($CmdLineRaw, '/(\w+)(?:[\s:]+(?:"([^"]+)"|([^\s/"]+)))?', 4)
If @error Then
ConsoleWrite("2001-2005 GmbH, Semiono. Coded by Amel27." & @CRLF & @CRLF)
ConsoleWrite(" //xregs.exe synops: ..." & @CRLF & @CRLF)
ConsoleWrite(@TAB & '{/val: "value1,value2,value3,etc."}|{/val:*}|{/add}...' & @CRLF)
ConsoleWrite(@TAB & '{/key: "[HKCR,HKCU,HKLM,HKU,HKCC]\Subkey"}' & @CRLF)
ConsoleWrite(@TAB & '{/reg: "[Drive:]\PATH\File.reg"}' & @CRLF) ; /out я переделал в $REG
	Exit -1 ; Ошибка: не указано ни одного параметра
EndIf

For $aParm In $aParms
    If UBound($aParm)=2 Then Assign($aParm[1], True)
    If UBound($aParm)>2 Then Assign($aParm[1], $aParm[UBound($aParm)-1])
Next

Global $iMode=8+2
If $add Then $iMode = 1

If $val=="*" Then $val = _RegEnumVals($key)
_RegValSave($reg, $key, $val, $iMode)

If @error = 1 Then
ConsoleWrite(@CRLF & "2001-2005 GmbH, Semiono. Coded by Amel27." & @CRLF)
ConsoleWrite("Failed! ..." & @CRLF)
	Exit @error ; ошибки выполнения _RegValSave()
EndIf

If @error = 0 Then 
ConsoleWrite(@CRLF & "2001-2005 GmbH, Semiono. Coded by Amel27." & @CRLF)
ConsoleWrite("Success! ..." & @CRLF)
EndIf
----

А почему Func _RegValSave($file, $key, $vals = "", $mode = 42) не даёт юникод файл?
Или это от BitAND() операций ещё зависит в данном скрипте?

----
Я ещё кое что на-бета тестил...
Вот проблемма:
[HKEY_LOCAL_MACHINE\Software\Classes\WinRAR\shell\open\command]
"@"="C:\I\Apps\WinRAR\WinRAR.exe "%1""

Должно быть:
[HKEY_LOCAL_MACHINE\Software\Classes\WinRAR\shell\open\command]
@="C:\\I\\Apps\\WinRAR\\WinRAR.exe \"%1\""

И ещё очень не хватает опции сохранения всех субключей...
Я попытался запустить без /val: свитчера, чтобы сохранить следущее:
xregs.exe /key: "HKLM\Software\Classes\.rar" /reg: "c:\file.reg"
xregs.exe /key: "HKLM\Software\Classes\WinRAR\DefaultIcon" /reg: "c:\file.reg" /add
xregs.exe /key: "HKLM\Software\Classes\WinRAR\shell\open\command" /reg: "c:\file.reg" /add
Но они затирают по-моему друг друга. Вообщем что-то там непонятное было...

Мне пришла идея! Может лучше зделать другие разделители для коммандной строки?
Чтобы вообще это не противоречило скрипту, и чтоб не надо было экранировать.

Ещё одна косметичиская фишка если не трудно, надо чтобы при /add не добавлялись @CRLF & @CLRF
перед каждым субкейем, но это я сам виноват, я к концу регфайла же дописал & @CLRF,
правда в конце файла это уместно.

-------
Полезное сообщение


Последний раз редактировалось semiono, 26-01-2010 в 07:12.


Отправлено: 04:40, 25-01-2010 | #29



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » Регфайл, синтаксис.

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
VBS/WHS/JS - синтаксис On Error Dr.Dark Программирование и базы данных 8 26-08-2008 11:42
Delphi - Синтаксис масивов в Паскале verdix Программирование и базы данных 3 13-05-2008 16:36
Delphi - *Флейм* | Delphi. Синтаксис. Использование WinAPI DillerInc Программирование и базы данных 60 13-03-2006 21:36
Синтаксис setup.iss ags Автоматическая установка приложений 11 06-03-2006 07:58
синтаксис php E-mail Вебмастеру 6 03-03-2005 22:42




 
Переход