Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Изменить значение параметра — Не INI файл! (http://forum.oszone.net/showthread.php?t=182805)

semiono 13-08-2010 00:06 1472549

Изменить значение параметра — Не INI файл!
 
Синтаксис обычный: параметр = значение, номер строки не известен.
Текущее значение неизвестно, и даже может быть пустым.
Например:
position.width=1152
position.height=816

Здесь видимо можно обрубить по знаку равенства "=" через StringRegExp(), но я не знаю как...

---
Я уже думал нашёл решение, просто переименовав файл, но проблемма оказалась в том,
что файл вдобавок не имеет секций []

kaster 13-08-2010 00:25 1472556

semiono, ну добавь секцию руками, обработай как INI, потом снова удали секцию.

semiono 13-08-2010 00:30 1472559

Можешь набросать как примерно? Потому что я с записью и удалением секции "нагорожу забор"!
Лучше посмотреть как это адекватно зделать.

Вот сам текст примерно такой

Код:

# SciTE session file

position.left=0
position.top=0
position.width=1152
position.height=816
position.maximize=1

mru.1.path=J:\[\Pebind\Alcohol\Patch\Script\Setup.au3
mru.2.path=H:\[\ENTRIES.au3
mru.3.path=C:\I\WinSxS\Process\New AutoIt v3 Script.au3

buffer.1.path=C:\I\WinSxS\Process\New AutoIt v3 Script.au3
buffer.1.position=46
buffer.1.current=1

А как можно секцию [test] вписать в начало файла или перед нужной строкой?

madmasles 13-08-2010 00:42 1472564

semiono,
Можно так попробовать:
Код:

$sStringW = 'position.width='
$sStringH = 'position.height='
$hFile = FileOpen(@UserProfileDir & '\SciTE.session', 0)
$sText = FileRead($hFile)
FileClose($hFile)
MsgBox(0, '', $sText)
$sText = StringRegExpReplace($sText, $sStringW & '\d{3,4}', $sStringW & @DesktopWidth)
$sText = StringRegExpReplace($sText, $sStringH & '\d{3,4}', $sStringH & @DesktopHeight)
MsgBox(0, '', $sText)


kaster 13-08-2010 00:48 1472567

Код:

$sPath = @ScriptDir & '\SciTE.session'; Scite.Session file path'
$sContent = '[Some Section]' & @CRLF & FileRead($sPath)
ConsoleWrite($sContent & @CRLF)
$hWrite = FileOpen($sPath, 2)
FileWrite($hWrite, $sContent)
FileClose($hWrite)
IniWrite($sPath, 'Some Section', 'position.width', @DesktopWidth)
IniWrite($sPath, 'Some Section', 'position.height', @DesktopHeight)
$hRead = FileOpen($sPath, 0)
FileReadLine($hRead)
$sContent = FileRead($hRead)
FileClose($hRead)
$hWrite = FileOpen($sPath, 2)
FileWrite($hWrite, $sContent)
FileClose($sContent)


semiono 13-08-2010 00:59 1472570

kaster, работает правильно как бы, но такое наблюдение, что снизу файл начинает зачищаться.
То-есть файл становиться всё меньше с каждым запуском снизу и даже начинает затирать сами строки position.width=1152 position.height=816... странно!

madmasles, если начальные значения не соответствуют разрядности, то не работает. :)
То-есть 1111 > 1152 нормально! Но 111 > не станет 1152

kaster 13-08-2010 01:08 1472571

semiono, не знаю. у меня ничего не зачищается. да и не должно по идее. возможно сам редактор привносит в этот файл изменения.

madmasles 13-08-2010 01:16 1472575

semiono,
Как скрипт kaster`a, так и мой отрабатывает у меня как надо. Если Вы его запускаете из открытого окна SciTE, то он возвращает старые значения. Закройте окно SciTE и запустите скрипт правой кнопкой через Run Script.
Цитата:

Цитата semiono
если начальные значения не соответствуют разрядности »

'\d{3,4}' значит любые 3 или 4 цифры подряд (от 000 до 9999). Можно для надежности поменять на '\d{1,4}' (0 - 9999). :)

Creat0R 13-08-2010 10:28 1472706

Вот функция которую я когда то писал для обработки ключей в файлах *.properties:

Код:

#include <Array.au3>

_FilePropertyWrite("File.properties", "Scripts", "MyScript.au3|SomeScript1.au3|SomeScript2.au3|SomeScript3.au3")

$aProperty = _FilePropertyRead("File.properties", "Scripts", "", 1)
_ArrayDisplay($aProperty)

Func _FilePropertyRead($sFile, $sProperty, $sDefault = "", $iRetArr = 1)
    Local $aFileRead = StringSplit(StringStripCR(FileRead($sFile)), @LF)
    Local $sRet, $sPattern = '(?i)^\s*\Q' & $sProperty & '\E\s*=\s*'

    For $i = 1 To $aFileRead[0]
        If StringRegExp($aFileRead[$i], $sPattern) Then
            $aFileRead[$i] = StringRegExpReplace($aFileRead[$i], $sPattern, '')

            If StringRight($aFileRead[$i], 1) = "\" Then
                $aFileRead[$i] = StringTrimRight($aFileRead[$i], 1)
            EndIf

            $sRet &= StringStripWS($aFileRead[$i], 3)

            For $j = $i+1 To $aFileRead[0]
                If StringInStr($aFileRead[$j], "=") Then
                    ExitLoop 2
                ElseIf StringLeft(StringStripWS($aFileRead[$j], 1), 1) <> "#" Then
                    If StringRight($aFileRead[$j], 1) = "\" Then
                        $aFileRead[$j] = StringTrimRight($aFileRead[$j], 1)
                    EndIf

                    $sRet &= " " & StringStripWS($aFileRead[$j], 3)
                EndIf
            Next

            ExitLoop
        EndIf
    Next

    If $sRet == "" Then
        $sRet = $sDefault
    Else
        $sRet = StringStripWS($sRet, 3)
    EndIf

    If $iRetArr Then
        Return StringSplit($sRet, "    ")
    EndIf

    Return $sRet
EndFunc

Func _FilePropertyWrite($sFile, $sProperty, $sValue, $iInsInLine = -1, $iPropsPerLine = 5)
    Local $aFileRead = StringSplit(StringStripCR(FileRead($sFile)), @LF)
    Local $sPropPattern = '(?i)^\s*(\Q' & $sProperty & '\E)\s*=\s*.*'
    Local $sKeyPattern = '^\s*([^=]+\s*=\s*|#)'
    Local $hFile, $sFileContent, $aValue, $sLine, $iPropFound = 0

    $aValue = StringSplit(StringReplace($sValue, '\', ''), '|')
    $sValue = ''

    For $i = 1 To $aValue[0]
        $sValue &= $aValue[$i]

        If $i < $aValue[0] Then
            If $i = 1 Or Mod($i - 1, $iPropsPerLine) = 0 Then
                $sValue &= ' \' & @CRLF & @TAB
            Else
                $sValue &= ' '
            EndIf
        EndIf
    Next

    For $i = 1 To $aFileRead[0]
        $sLine = $aFileRead[$i]

        If StringRegExp($aFileRead[$i], $sPropPattern) Then
            If $iInsInLine = -1 Then
                $iPropFound = 1
                $sLine = StringRegExpReplace($aFileRead[$i], $sPropPattern, '\1=' & StringReplace($sValue, '\', '\\'))
            EndIf

            For $j = $i+1 To $aFileRead[0]
                If StringRegExp($aFileRead[$j], $sKeyPattern) Or $i >= $aFileRead[0] Then
                    ExitLoop
                EndIf

                $i += 1
            Next

            If $iInsInLine <> -1 Then
                ContinueLoop
            EndIf
        EndIf

        $sFileContent &= $sLine

        If $i < $aFileRead[0] Then
            $sFileContent &= @CRLF
        EndIf
    Next

    If $iInsInLine <> -1 Then
        $aFileRead = StringSplit(StringStripCR($sFileContent), @LF)
        $sFileContent = ''

        For $i = 1 To $aFileRead[0]
            If $i = $iInsInLine Then
                $iPropFound = 1
                $sFileContent &= $sProperty & "=" & $sValue & @CRLF & $aFileRead[$i]
            Else
                $sFileContent &= $aFileRead[$i]
            EndIf

            If $i < $aFileRead[0] Then
                $sFileContent &= @CRLF
            EndIf
        Next
    EndIf

    If Not $iPropFound Then
        If $sFileContent <> '' And StringRight($sFileContent, 2) <> @CRLF Then
            $sFileContent &= @CRLF
        EndIf

        $sFileContent &= $sProperty & "=" & $sValue
    EndIf

    $hFile = FileOpen($sFile, 2)
    FileWrite($hFile, $sFileContent)
    Return FileClose($hFile)
EndFunc

работает также с многострочными значениями (разделённые слешем «\»).

Creat0R 13-08-2010 11:08 1472728

Добавил в пример выше функцию для записи, также поддерживает запись многострочного значения.

semiono 13-08-2010 12:05 1472774

Вчера до ночи сидел, правда у меня сидение малопродуктивное, сейчас буду посмотреть.
Про SciTE верно, я сам подумал, что он может вносить изменения, ведь это его конфиг,
однако сразу же засомневался, так как я в основном кликом скрипт открывал.
Ещё одна идея есть о том, что я в папке профиля чудил, а на папки профиля сколько помню
в различных логах выводится, что файл защищён правами... нечто такое помню...
Но не будем об этом, пусть спишется как странный глюк непонятный ))
Ещё возможно, что я быстро файл открывал посмотреть, и якобы он не весь прописался,
такое тоже вероятно, но тогда получается, что скрипт слишком уж доооолго работает!
Ладно с этим понятно, раз уж всё разложили по полочкам буду доверять коду.
Только теперь не знаю что лучше, все три варианта, но Creat0R,
интригующе самый солидный скрипт! Ок!

Кстати, я уже говорил давно, жаль что такого простого среди функций нет.
А самое лучшее бы было из ini- функций как-то превратить, так как там именно под задачу заточенно,
возможно я ошибаюсь. И конечно возмутительно что FileWright пишет дополнение в конец файла,
кому такая наивность тут нужна! Эх autoit3.com (C) всё чаще разочароывает, так как идея скриптов
идея быстрого и простого создания скриптов... 8-)

Creat0R 13-08-2010 12:26 1472792

Обновил функцию для записи, теперь можно указать номер строки куда будет записываться ключ, при этом ключ из старого местоположения удаляется. Т.е предотвращается дублирование записи.

semiono 13-08-2010 13:03 1472820

madmasles, а ведь твой скрипт не изменяет файл! Чем же я сам запишу $sText, FileWright тупо добавит строку в файл.


Creat0R, я не знаю как твою функцию юзать, это для просвещённых. Вчастности, непонятно как указать нужное значение.

Creat0R 13-08-2010 13:08 1472824

Цитата:

Цитата semiono
я не знаю как твою функцию юзать »

Я же показал пример:

Код:

_FilePropertyWrite("Scite.Session", "position.width", "666")
Цитата:

Цитата semiono
непонятно как указать нужное значение »

Ну это уже тебе решать, какое туда записывать значение :)

semiono 13-08-2010 13:16 1472829

Внимание, работает код от kaster! Фрагменты # SciTE session file с низу.

buffer.1.path=C:\I\WinSxS\Process\New AutoIt v3 Script.au3
buffer.1.position=46
buffer.1.current=1

---->8

buffer.1.path=C:\I\WinSxS\Process\New AutoIt v3 Scr

--->8

buffe

---->8

Конфиг съедает сам себя :)

Цитата:

Цитата Creat0R
Ну это уже тебе решать, какое туда записывать значение »

Не какое, а куда. Вот сейчас понял.

Creat0R 13-08-2010 13:23 1472835

Цитата:

Цитата semiono
Я уже думал нашёл решение, просто переименовав файл, но проблемма оказалась в том,
что файл вдобавок не имеет секций [] »

Вот немного изменённый пример Kaster'а (там у него кстати ошибка в FileClose($sContent) :) - возможно отсюда и проблема с затиранием строк):

Код:

$sPath = @ScriptDir & '\Scite.Session'

_IniWriteProperty($sPath, 'position.width', @DesktopWidth)
_IniWriteProperty($sPath, 'position.height', @DesktopHeight)

Func _IniWriteProperty($sIni, $sProperty, $sValue)
    Local $sSection, $sContent, $hWrite

    $sSection = 'Section'
    $sContent = '[' & $sSection & ']' & @CRLF & FileRead($sIni)

    $hWrite = FileOpen($sIni, 2)
    FileWrite($hWrite, $sContent)
    FileClose($hWrite)

    IniWrite($sIni, $sSection, $sProperty, $sValue)
    IniWrite($sIni, $sSection, $sProperty, $sValue)

    $sContent = FileRead($sIni)

    $hWrite = FileOpen($sIni, 2)
    FileWrite($hWrite, StringRegExpReplace($sContent, '^\Q[' & $sSection & ']\E(\r\n)*', ''))
    FileClose($hWrite)
EndFunc


semiono 13-08-2010 13:34 1472842

Вот это другое дело! Работает даже при буквенных значениях =zzzzzzzzzzzzzzzzzzzz любой длины!
И при пустом значении =
Ну для правильности добавим правильный путь $sPath = @UserProfileDir & '\SciTE.session'
Это же реальный SciTE.session конфиг, так что можете тоже пользоваться!
kaster, madmasles, Creat0R, спасиб!
:)

Creat0R 13-08-2010 13:43 1472853

Цитата:

Цитата semiono
Работает даже при буквенных значениях =zzzzzzzzzzzzzzzzzzzz любой длины! »

В варианте с «_IniWriteProperty» в отличии от варианта с «_FilePropertyWrite» не любой длины, но думаю для тебя хватит ;)

semiono 13-08-2010 13:53 1472864

$sPath = @UserProfileDir & '\SciTE.session'

_IniWriteProperty($sPath, 'position.left', '0')
_IniWriteProperty($sPath, 'position.top', '0')
_IniWriteProperty($sPath, 'position.width', @DesktopWidth)
_IniWriteProperty($sPath, 'position.height', @DesktopHeight-52)
_IniWriteProperty($sPath, 'position.maximize', '0')

Все параметры, заодно. :)

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

kaster 13-08-2010 13:53 1472865

Creat0R, ну не знаю. у меня ведь ничего не съедалось. Да и потом, логика подсказывает, что закрытие неверного хендла всего лишь вернет 0. А после этой строки нет ничего, стало быть скрипт завершится и файл сам закроется.

madmasles 13-08-2010 13:56 1472871

semiono,
Если Вы устанавливаете значения @DesktopWidth и @DesktopHeight, то надо, наверное проверить, чтобы position.left и position.top были равны 0.

semiono 13-08-2010 14:12 1472881

madmasles, да. Только не проверить, а сразу записать. Но там важнее всего было сбросить maximize.

Скрипт вдобавок ещё и создаёт файл если его не было изначально!


Время: 13:54.

Время: 13:54.
© OSzone.net 2001-