|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » Регфайл, синтаксис. |
|
|
Регфайл, синтаксис.
|
Ветеран Сообщения: 842 |
Профиль | Отправить PM | Цитировать
Думаю пора обсудить написание валидных регфайлов средствами 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 Однако, большую сложность думаю представляет запись значений параметров в валидном виде для регфалов! Например, все типы кроме REG_SZ и REG_DWORD имеют запись вида = hex(2): Причём, понятно что REG_EXPAND_SZ содержит юникод, экспортирующийся в виде шеснадцетиричного кода разделённого запятыми в регфайл. Закрывается строка нуевым символом, то-есть двумя байтами нулей ',00,00' (впрочем это так же актуально и для multisz и для binary) Несмотря на то, что строки могут быть размещены без переносов, и это работает, однако майкрософт придумала способ записи разделяемой слеш, для переноса строки. Это красиво и хотелось бы тоже этому следовать. Длина строк в такой записи содержит 25 байт разделённых запятыми, строки начинается с двух пробелов и заканчивается слеш, если нужен перенос Однако первая строка имеет не постоянную длину относительно имени переменной. Минимальная строка содержит 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,\ < строка стала короче "zzz"=dword:0001e240 И другие (zero-lenth-binary-value) "value1"=hex(0): У меня просьба, сделайте свои предложения по поводу кода autoit, и быть может это соберёться в некий включаемый файлик? Вопрос: можно ли получить юникод или бинарную не ascii строку в перменную и затем разделить все байты строки запятыми? Ну и особое желание - это установить слеши по схеме регфайла, тоесть с расчётом длинны, длин и т.п. Ещё проще вопрос, как записать запятую через каждые два символа, заранее неизвестной строки... aa,bb,ab,ac,.... |
|
------- Отправлено: 20:17, 22-06-2009 |
Ветеран Сообщения: 842
|
Профиль | Отправить PM | Цитировать Молодцы! Приставить к награде пора! Я в восторге!
|
------- Отправлено: 19:52, 24-06-2009 | #21 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 460
|
Профиль | Отправить PM | Цитировать 7 миллионов доллоров, semiono, 7 миллионов
+ еще обновление: Цитата:
|
|
------- Последний раз редактировалось proxy, 24-06-2009 в 22:25. Отправлено: 20:45, 24-06-2009 | #22 |
Googler Сообщения: 3665
|
Профиль | Отправить 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:
|
|
Отправлено: 09:21, 25-06-2009 | #23 |
Старожил Сообщения: 460
|
Профиль | Отправить PM | Цитировать Цитата amel27:
Цитата:
пора, semiono, тему завершать? |
||
------- Отправлено: 10:35, 25-06-2009 | #24 |
Ветеран Сообщения: 842
|
Профиль | Отправить PM | Цитировать Завершение уже не зависит от моего решения
Однако я нажал. +1 |
------- Отправлено: 04:23, 26-06-2009 | #25 |
Ветеран Сообщения: 842
|
Профиль | Отправить PM | Цитировать Чтоб это доброе дело продолжалось, было б, зделать утиль regEx.exe которая читает ввод командой строки,
например, # regex /export HKLM\Microsoft\'Windows NT\.la -la-la' C:\'.my reg.reg' и делает это. ? |
------- Отправлено: 21:26, 27-06-2009 | #26 |
Googler Сообщения: 3665
|
Профиль | Отправить PM | Цитировать Цитата semiono:
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 @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 |
Ветеран Сообщения: 842
|
Профиль | Отправить 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 |
Ветеран Сообщения: 842
|
Профиль | Отправить 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 |
|
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
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 | Вебмастеру | 6 | 03-03-2005 22:42 |
|