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

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

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

Аватара для semiono

Ветеран


Сообщения: 842
Благодарности: 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

 

Аватара для proxy

Старожил


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

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


Получается следующий результат:

Код: Выделить весь код
$sSerial = 'VMKJGNDIDNWLDMKJGNDIDNWLD'
MsgBox(0, 'Строка для reg-файла', _StringToRegFileFormat($sSerial, 'REG_EXPAND_SZ'))

Func _StringToRegFileFormat($sData, $sType, $iSlash=10)
    Local $sHex, $iHexLength, $aData, $sDataResult, $i, $j=4
    If $iSlash < 0 OR ($iSlash > 0 AND $iSlash < 4) Then $iSlash = 4

    Switch $sType
        Case 'REG_DWORD'
            Return 'dword:' & Hex($sData, 8)
        Case 'REG_BINARY'
            $sType = 'hex:'
            $iHexLength = 3
        Case 'REG_EXPAND_SZ'
            $sType = 'hex(2):'
            $iHexLength = 2
        Case 'REG_MULTI_SZ'
            $sType = 'hex(7):'
            $iHexLength = 7
        Case Else
            Return '"' & $sData & '"'
    EndSwitch

    $sData = StringLower(Hex(StringToBinary($sData, 2), $iHexLength))
    For $i=1 To StringLen($sData) Step 2
        $sDataResult &= StringMid($sData, $i, 2) & ','
        If $j == $iSlash Then
            $j = 0
            $sDataResult &= '\' & @CRLF
        EndIf
        $j += 1
    Next

    Return $sType & $sDataResult & '00,00'
EndFunc
вариант без слешей:
Код: Выделить весь код
_StringToRegFileFormat($sSerial, 'REG_EXPAND_SZ', 0)
Тип: REG_SZ записывается как есть, в кавычках:
Цитата:
"Name Value"="Value Data"

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


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

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

Отправлено: 03:17, 24-06-2009 | #11



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

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


Аватара для SyDr

Старожил


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

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


Цитата semiono:
Минимальная строка содержит 22 байта разделённых запятыми, и начинает убавляться на один байт »
Откуда инфа? Вручную? У меня тогда немного по другому это сформулировано:
Если длина строки более 76 символов - выполняется перенос. Следующая строка содержит в начале два пробела.


Вроде что-то написал Работает вроде правильно. Пока проблемка с нулевым значением. Да и сам код выглядит громоздко.

-------

"Что мы думаем, знаем или во что верим в конце концов не так уж и важно.
Важно лишь то, что мы делаем."
Джон Раскин

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

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


Аватара для proxy

Старожил


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

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


Цитата:
Вроде что-то написал Работает вроде правильно. Пока проблемка с нулевым значением. Да и сам код выглядит громоздко.
а код чего? на тему топик-стартера?

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


Отправлено: 12:27, 24-06-2009 | #13


Аватара для SyDr

Старожил


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

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


Да.
Изменил немного. Стало меньше. Но всё равно много (хотя, в принципе, знаю как ещё больше можно уменьшить):
Код: Выделить весь код
Func RegValueReadAndConvert($KeyName, $ValueName)
    Local $Data = RegRead($KeyName, $ValueName)
    Local $Type = @extended
    Local $Return = '"' & $ValueName & '"='
    Local $Temp = ""
    Local $ArrT[1]

    Switch $Type

        Case $REG_SZ
            Return $Return & '"' & $Data & '"'

        Case $REG_EXPAND_SZ
            $Data = StringReplace(StringToBinary($Data, 2), "0x", "")
            $Temp = $Return & "hex(2):"
            $Length = StringLen($Data) / 2
            For $i = 1 To $Length + 3
                If $I < $Length + 1 Then
                    $Temp &= StringMid($Data, $I * 2 - 1, 2) & ","
                Else
                    $Temp &= "00"
                    If $I < $Length + 3 Then $Temp &= ","
                EndIf
                $ArrT = StringSplit($Temp, @LF)
                If StringLen($ArrT[$ArrT[0]]) > 76 Then $Temp &= "\" & @CRLF & "  " ; два пробела
            Next
            Return $Temp

        Case $REG_BINARY
            $Data = StringReplace($Data, "0x", "")
            $Temp = $Return & "hex:"
            For $i = 1 To StringLen($Data) / 2 - 1
                $Temp &= StringMid($Data, $I * 2 - 1, 2) & ","
                $ArrT = StringSplit($Temp, @LF)
                If StringLen($ArrT[$ArrT[0]]) > 76 Then $Temp &= "\" & @CRLF & "  " ; два пробела
            Next
            $Temp &= StringMid($Data, StringLen($Data) - 1, 2)
            Return $Temp

        Case $REG_DWORD
            Return $Return & "dword:" & Hex($Data)

        Case $REG_MULTI_SZ
            $Data = StringReplace(StringToBinary($Data, 2), "0x", "")
            $Temp = $Return & "hex(2):"
            $Length = StringLen($Data) / 2
            For $i = 1 To $Length + 4
                If $I < $Length + 1 Then
                    $Temp &= StringMid($Data, $I * 2 - 1, 2) & ","
                Else
                    $Temp &= "00"
                    If $I < $Length + 4 Then $Temp &= ","
                EndIf
                $ArrT = StringSplit($Temp, @LF)
                If StringLen($ArrT[$ArrT[0]]) > 76 Then $Temp &= "\" & @CRLF & "  " ; два пробела
            Next
            Return $Temp

    EndSwitch
EndFunc

-------

"Что мы думаем, знаем или во что верим в конце концов не так уж и важно.
Важно лишь то, что мы делаем."
Джон Раскин

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

Отправлено: 12:31, 24-06-2009 | #14


Аватара для proxy

Старожил


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

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


+ мой вариант:
Код: Выделить весь код
#region: - Options
    Opt('MustDeclareVars',      1)
    Opt('TrayIconDebug',        1)
    Opt('TrayIconHide',         0)
#endregion

Local $sFilePath    = 'd:\reg.reg'
Local $sRegKey      = 'HKEY_LOCAL_MACHINE\SYSTEM'
Local $sValueName   = 'SN'
Local $sValueType   = 'REG_EXPAND_SZ'
Local $fAllInKey    = 1
Local $iSlash       = 10

_CreatRegFile($sFilePath, $sRegKey, $sValueName, $sValueType, $fAllInKey, $iSlash)

Func _CreatRegFile($sFilePath, $sRegKey, $sValueName, $sValueType, $fAllInKey=0, $iSlash=10)
    Local Const $REG_SZ         = 1
    Local Const $REG_EXPAND_SZ  = 2
    Local Const $REG_BINARY     = 3
    Local Const $REG_DWORD      = 4
    Local Const $REG_MULTI_SZ   = 7

    Local $hFile, $i=1
    Local $sFileContent = 'Windows Registry Editor Version 5.00'
    $sRegKey = StringRegExpReplace($sRegKey, '\\+$', '')

    While 1
        If $fAllInKey Then
            $sValueName = RegEnumVal($sRegKey, $i)
            If @error <> 0 Then ExitLoop

            Switch @extended
                Case $REG_SZ
                    $sValueType = 'REG_SZ'
                Case $REG_EXPAND_SZ
                    $sValueType = 'REG_EXPAND_SZ'
                Case $REG_BINARY
                    $sValueType = 'REG_BINARY'
                Case $REG_DWORD
                    $sValueType = 'REG_DWORD'
                Case $REG_MULTI_SZ
                    $sValueType = 'REG_MULTI_SZ'
            EndSwitch
        EndIf

        $sFileContent &=  @CRLF & @CRLF & '[' & $sRegKey & ']' & @CRLF & _StringToRegFileFormat($sValueName, RegRead($sRegKey, $sValueName), $sValueType, $iSlash)
        If NOT $fAllInKey Then ExitLoop
        $i += 1
    WEnd

    $hFile = FileOpen($sFilePath, 8+2)
    FileWrite($hFile, $sFileContent)
    FileClose($hFile)
EndFunc

Func _StringToRegFileFormat($sName, $sData, $sType, $iSlash=10)
    Local   $sHex, $iHexLength, $iNameLen, $iStartLen, $aResult, $sResult, $i

    Switch $sType
        Case 'REG_DWORD'
            Return 'dword:' & Hex($sData, 8)
        Case 'REG_BINARY'
            $sType = 'hex:'
            $iHexLength = 3
        Case 'REG_EXPAND_SZ'
            $sType = 'hex(2):'
            $iHexLength = 2
        Case 'REG_MULTI_SZ'
            $sType = 'hex(7):'
            $iHexLength = 7
        Case Else
            Return '"' & $sData & '"'
    EndSwitch

    $iNameLen =  Floor(StringLen($sName & $sType) / 2)
    $sResult = StringLower(Hex(StringToBinary($sData, 2), 2))  & '0000'

    If StringLen($sResult)+(StringLen($sResult)/2)-1 > 76 Then $iSlash = 10

    If $iNameLen > $iSlash Then
        $iStartLen = 0
    Else
        $iStartLen = $iSlash - $iNameLen + 6
    EndIf

    If StringLen($sResult)+(StringLen($sResult)/2)-1 < StringLen($sName & $sType) Then $iSlash = 0

    If $iNameLen < $iStartLen Then $iStartLen = $iSlash - $iNameLen + $iSlash-4
    If Mod($iStartLen, 2) <> 0 Then $iStartLen += 1

    Dim $aResult[2]
    $aResult[0] = StringLeft($sResult, $iStartLen)
    $aResult[1] = StringMid($sResult,  $iStartLen+1)

    For $i=0 To 1
        $aResult[$i] = StringRegExpReplace($aResult[$i], '([a-z0-9]{2,2})', '\1,')
        If $i Then
            If $iSlash Then $aResult[$i] = '\' & @CRLF & StringRegExpReplace($aResult[$i], '(.{' & ($iSlash*3)-1 & '},)', '\1\\' & @CRLF)
            $aResult[$i] = StringRegExpReplace($aResult[$i], ',+$', '')
        EndIf
    Next

    $sResult = $aResult[0] & $aResult[1]

    Return '"' & $sName & '"=' & $sType & $sResult & @CRLF
EndFunc
Можно считывать как отдельную величину, так и все имеющиеся величины в ключе.
Учтено: длина строки < 76, и @CRLF в конце.
Уже лучше расставляются слеши, вся разбивка на StringRegExpReplace.

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


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


Отправлено: 14:30, 24-06-2009 | #15


Аватара для proxy

Старожил


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

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


Sylver Dragon:
Код: Выделить весь код
Local Const $REG_SZ         = 1
Local Const $REG_EXPAND_SZ  = 2
Local Const $REG_BINARY     = 3
Local Const $REG_DWORD      = 4
Local Const $REG_MULTI_SZ   = 7
потерялись?



Hex конвертацию можно упростить:
Код: Выделить весь код
$sSerial = 'VMKJGNDIDNWLDMKJGNDIDNWLD'
MsgBox(0, $sSerial, Hex(StringToBinary($sSerial, 2), 7))


Расстановка запятых, так не проще?
Код: Выделить весь код
$sData = 'VMKJGNDIDNWLDMKJGNDIDNWLD'
For $i=1 To StringLen($sData) Step 2
    $sDataResult &= StringMid($sData, $i, 2) & ','
Next
MsgBox(0, $sData, $sDataResult)


Расстановка запятых + слеши:
Код: Выделить весь код
$sData = 'VMKJGNDIDNWLDMKJGNDIDNWLD'
$iSlash = 10
For $i=1 To StringLen($sData) Step 2
    If $j == $iSlash Then
        $j = 0
        $sDataResult &= '\' & @CRLF
    EndIf
    $j += 1
    $sDataResult &= StringMid($sData, $i, 2) & ','
Next
MsgBox(0, $sData, $sDataResult)

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

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

Отправлено: 14:56, 24-06-2009 | #16


Аватара для SyDr

Старожил


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

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


Разве всё надо в hex конвертить?

Цитата proxy:
Расстановка запятых, так не проще? »
Проще. Но ещё есть "закрывающие" нули и в конце строки запятая не нужна и также разделение на строки (If StringLen > 76). Возвращаемое функцией значение соответсвует тому, что я вижу в .reg файле (без конечного @CRLF).


Цитата proxy:
потерялись? »
Я только функцию копировал. Константы были в основном скрипте.

-------

"Что мы думаем, знаем или во что верим в конце концов не так уж и важно.
Важно лишь то, что мы делаем."
Джон Раскин


Отправлено: 15:08, 24-06-2009 | #17


Аватара для proxy

Старожил


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

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


Цитата Sylver Dragon:
Проще. Но ещё есть "закрывающие" нули и в конце строки запятая не нужна »
ну это само собой, в скрипте, выше получается так:
Цитата:
$sData = StringLower(Hex(StringToBinary($sData, 2), $iHexLength)) & '0000'
For $i=1 To StringLen($sData) Step 2
If $j == $iSlash Then
$j = 0
$sDataResult &= '\' & @CRLF
EndIf
$j += 1
$sDataResult &= StringMid($sData, $i, 2) & ','
Next

Return '"' & $sName & '"=' & $sType & StringRegExpReplace($sDataResult, ',+$', '')


Закрывающие нули:
Цитата:
$sData = StringLower(Hex(StringToBinary($sData, 2), $iHexLength)) & '0000'

Удаление запятой:
Цитата:
StringRegExpReplace($sDataResult, ',+$', '')


Цитата:
(If StringLen > 76)
вот это упустил из виду ....76 с учетом запятых?



Цитата:
(без конечного @CRLF).
специально его убрал, а так принципиально нужен?


...обновил..

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


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


Отправлено: 17:44, 24-06-2009 | #18


Аватара для SyDr

Старожил


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

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


StringRegExpReplace($TempValue, "([^,]{2})", "$0,") - расстановка запятых после каждого второго символа (в конце тоже будет).
Цитата proxy:
вот это упустил из виду ....76 с учетом запятых? »
76 с учётом всего. И пробелов в начале и названия ключа. Ну, или другими словами если 77, 78 или 79 символов.
Цитата proxy:
специально его убрал, а так принципиально нужен? »
Ну. Если FileWriteLine - то не нужно.
Плюс, после каждого раздела следует ещё один @CRLF

-------

"Что мы думаем, знаем или во что верим в конце концов не так уж и важно.
Важно лишь то, что мы делаем."
Джон Раскин

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

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


Аватара для proxy

Старожил


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

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


Цитата Sylver Dragon:
StringRegExpReplace($TempValue, "([^,]{2})", "$0,") »
ааагггррххх..... Круть!!

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

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

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



Компьютерный форум 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




 
Переход