![]() |
Регфайл, синтаксис.
Думаю пора обсудить написание валидных регфайлов средствами AutoIt3.
Хочется объединить всё вместе, как некое знание и рассмотреть все встречающиеся особенности записи различных типов параметров. Сразу же хочеться отметить различие реестров x86 и x64, и в то же время рег синтакс исключающий записи вида HKLM/HKCU и т.п. Здесь могут быть полезными выключатели Код:
Switch @OSArch Код:
$sFileContent = _ Однако, большую сложность думаю представляет запись значений параметров в валидном виде для регфалов! Например, все типы кроме 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,\ "zzz"=dword:0001e240 И другие (zero-lenth-binary-value) "value1"=hex(0): У меня просьба, сделайте свои предложения по поводу кода autoit, и быть может это соберёться в некий включаемый файлик? Вопрос: можно ли получить юникод или бинарную не ascii строку в перменную и затем разделить все байты строки запятыми? Ну и особое желание - это установить слеши по схеме регфайла, тоесть с расчётом длинны, длин и т.п. :) Ещё проще вопрос, как записать запятую через каждые два символа, заранее неизвестной строки... aa,bb,ab,ac,.... |
Простите а зачем это нужно ???
|
FlatX007, а дело в том, что вот такая ситуация:
Задача: необходимо создать файл типа .reg, который будет записывать (или обновлять) данные в реестре велечины типа REG_EXPAND_SZ. В реестре это будет выглядеть так: Цитата:
А вот в .reg файле это будет выглядеть так: Цитата:
Дело в том, что значения в .reg файле записываются следующим образом: Цитата:
Соответсвенно появился интерес накатать функции, для форматирования/перекодировки значений реестового типа REG_BINARY, REG_DWORD, REG_SZ и т.д. в формат .reg файла hex(3), hex(4), hex(1) и т.д. Для типа REG_EXPAND_SZ, ни чего умней не родилось, как это: Код:
$sRegKey = 'HKEY_CURRENT_USER\Software\DashSignature\Knagalis' Вот и все, в этом и вопрос....осталось немного покодить ;) |
А что утилита ConvRegToAu3 - неумеет этого делать ?
|
Цитата:
FlatX007, ээ-хеее-ххххххххх......стал бы я возиться если уже все есть? - нет конечно )) конечно может и есть уже, но пока не нашел )) Задача - с помощью AutoIt создать reg файл. А не из reg файла RegWrite функци... )) |
А всё допёрло ... я сначало невкурил.
|
FlatX007, ещё хочу напомнить то, что reg.exe expand /? имеет тоже ограничения.
Я бы хотел иметь замену reg.exe, так как утилита коммандной строки сама по себе хороша, потому что можно использовать батники, а так же вызывать из InnoSetup, но стандартная утилита не всё умеет, а жаль. |
Дайте спецификацию .reg файлов. То есть как выглядит в нём каждый из указанных типов значений.
Для любого ли типа необходимо ковертить в hex? Какое условие переноса строки? |
Sylver Dragon, а мне дайте 7 миллионов долларов ))))))))))))))))))))))))))
И то есть, почему ни кто не приносит кофе мне в постел? ;) Где моя любимая кока-кола?? Какие условия возврата d-link барахла? )))))))))) Спецификацию файлов, типа которых разработан в Miscrosoft....что может быть проще? хотя и не совсем спецификация (( Цитата:
...ааагрррх, на самом деле форматирование выглядит вот так: Код:
$sSerial = 'VMKJGNDIDNWLDMKJGNDIDNWLD' |
Перенос строки я посчитал, смотрите выше:
Цитата:
будут записываться одинакого, в том числе и переносы. Так как вроде бы нет причины их записывать иначе. И для переноса строк в MULTI_SZ в самом регфайле ничего не будет предусмотренно, так как это выполняется самим кодом, а это значит, что там в закрытии строк будут какие-то нули... два байта или четыре, не знаю... 00,00,00,00 типа того! То-есть само оформление будет обычным, но байт-контент надо уже контролировать... В InnoSetup переносы в multisz выполняет {break} Характерные примеры multisz (WinXP) HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager BootExecute = Код:
autocheck autochk /k:D /k:E /k:F /k:G /k:H /k:I /k:J /k:K /k:L /k:M /k:N /k:O /k:P /k:Q /k:R /k:S /k:T /k:U /k:V /k:W /k:X /k:Y /k:Z * Я как-то возился над PendingFileRenameOperating так и не понял ничего, запарился его тестить перезагрузками :) |
Получается следующий результат:
Код:
$sSerial = 'VMKJGNDIDNWLDMKJGNDIDNWLD' Код:
_StringToRegFileFormat($sSerial, 'REG_EXPAND_SZ', 0) Цитата:
|
Цитата:
Если длина строки более 76 символов - выполняется перенос. Следующая строка содержит в начале два пробела. Вроде что-то написал :) Работает вроде правильно. Пока проблемка с нулевым значением. Да и сам код выглядит громоздко. |
Цитата:
|
Да.
Изменил немного. Стало меньше. Но всё равно много (хотя, в принципе, знаю как ещё больше можно уменьшить): Код:
Func RegValueReadAndConvert($KeyName, $ValueName) |
+ мой вариант:
Код:
#region: - Options Учтено: длина строки < 76, и @CRLF в конце. Уже лучше расставляются слеши, вся разбивка на StringRegExpReplace. |
Sylver Dragon:
Код:
Local Const $REG_SZ = 1 Hex конвертацию можно упростить: Код:
$sSerial = 'VMKJGNDIDNWLDMKJGNDIDNWLD' Расстановка запятых, так не проще? Код:
$sData = 'VMKJGNDIDNWLDMKJGNDIDNWLD' Расстановка запятых + слеши: Код:
$sData = 'VMKJGNDIDNWLDMKJGNDIDNWLD' |
Разве всё надо в hex конвертить?
Цитата:
Цитата:
|
Цитата:
Цитата:
Закрывающие нули: Цитата:
Удаление запятой: Цитата:
Цитата:
Цитата:
...обновил.. |
StringRegExpReplace($TempValue, "([^,]{2})", "$0,") - расстановка запятых после каждого второго символа (в конце тоже будет).
Цитата:
Цитата:
Плюс, после каждого раздела следует ещё один @CRLF |
Цитата:
|
:o Молодцы! Приставить к награде пора! Я в восторге!
|
7 миллионов доллоров, semiono, 7 миллионов :yahoo:
+ еще обновление: Цитата:
|
коль пошла такая пьянка, кину и свой вариант :)
Код:
$hFile = FileOpen("C:\TEST\TEST.reg", 8+2) Цитата:
|
Цитата:
Цитата:
пора, semiono, тему завершать? |
Завершение уже не зависит от моего решения :)
Однако я нажал. +1 |
Чтоб это доброе дело продолжалось, было б, зделать утиль regEx.exe которая читает ввод командой строки,
например, # regex /export HKLM\Microsoft\'Windows NT\.la -la-la' C:\'.my reg.reg' и делает это. ? :) |
Цитата:
Код:
Global $KEY, $VAL, $ADD = False, $OUT=StringRegExpReplace(@ScriptFullPath,".[^.]+$", ".reg") Код:
@Echo Off |
****
Регистр букв я сам исправил! Надеюсь правильно 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... выводилось согласно логике? |
Оказывается наполовину работает! Вообщем такое срабатывает /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) А почему 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, правда в конце файла это уместно. |
Время: 02:13. |
Время: 02:13.
© OSzone.net 2001-