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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Изменение параметров в .ini файле (http://forum.oszone.net/showthread.php?t=331679)

Stalker_AleX333 05-12-2017 18:49 2782548

Изменение параметров в .ini файле
 
Требуется изменить значения определенных параметров в ini файле, находящемуся по заранее известному пути. При отсутствии нужного параметра, его необходимо добавить в соответствующий раздел вида:

[Interface]
fMouseCursorSpeed=1.0000
bDialogueSubtitles=0
bGeneralSubtitles=0
bShowCompass=1
[GamePlay]
bShowFloatingQuestMarkers=1
bShowQuestMarkers=1
iDifficulty=0
[Controls]
fMouseHeadingSensitivity=0.0200
fGamepadHeadingSensitivity=0.6667
bAlwaysRunByDefault=1
bInvertYValues=0
bGamePadRumble=1
bUseKinect=0
[Particles]
iMaxDesired=750
[SaveGame]
fAutosaveEveryXMins=15.0000

и т.д.

Я полистал последние 5-7 страниц форума и нашел там приблизительно подходящий мне код:
Код:

@Echo Off
CALL :REPLINE "file.ini" "Server_address=" "Server_address=192.1.1.1"
CALL :REPLINE "file.ini" "Server_port=" "Server_port=8080"
:REPLINE
If Not Exist "%~1" Exit /B 1
If Exist "%~dpn1.tmp" DEL /F/Q "%~dpn1.tmp"
Set $N=0& For /F "Delims=:" %%i In ('FindStr /BINRC:" *%~2" "%~1"') Do Set $N=%%i
If %$N% NEQ 0 For /F "Tokens=1* Delims=:" %%i In ('FindStr /ENRC:"$" "%~1"') Do If "%%i"=="%$N%" (
Echo %~3>>"%~dpn1.tmp" ) ELSE Echo.%%j>>"%~dpn1.tmp"
If Exist "%~dpn1.tmp" If Exist "%~1" DEL /F/Q "%~1"
If Exist "%~dpn1.tmp" REN "%~dpn1.tmp" "%~nx1"
Exit /B 0

Правда, пока никак не могу понять, как мне его адаптировать под свои нужды.

Вот мой список значений, которые требуется установить (в самом файле порядок группировки секций может быть другим):

[Display]
bFXAAEnabled=0
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100
[MAIN]
fSkyCellRefFadeDistance=600000.0000
[Trees]
uiMaxSkinnedTreesToRender=200
[Water]
iWaterReflectHeight=1024
iWaterReflectWidth=1024


Т.е. выглядеть это должно как-то так:

Код:

set "SkyrimPrefs=%USERPROFILE%\Documents\My Games\Skyrim Special Edition"
call :repline "SkyrimPrefs.ini" "bFXAAEnabled=" "bFXAAEnabled=0"
call :repline "SkyrimPrefs.ini" "fTreesMidLODSwitchDist=" "fTreesMidLODSwitchDist=8192.000"
call :repline "SkyrimPrefs.ini" "fMeshLODLevel1FadeTreeDistance=" "fMeshLODLevel1FadeTreeDistance=6144.000"
и т.д.

А если не нашли нужный параметр, найти его секцию (прим. [MAIN]) и добавить в ее конец, не трогая остальные.

Iska 05-12-2017 19:02 2782555

Цитата:

Цитата Stalker_AleX333
в ini файле, »

Кодировка файла?

Цитата:

Цитата Stalker_AleX333
находящемуся по заранее известному пути.

set "SkyrimPrefs=%USERPROFILE%\Documents\My Games\Skyrim Special Edition" »

…и на XP Ваш код не найдёт файл.

Stalker_AleX333 05-12-2017 19:12 2782557

Кодировка файла ANSI.

CMD-шник точно не будет запускаться на WinXP, в данном случае это не проблема.

Iska 05-12-2017 19:36 2782565

Ждите коллег, может помогут.

megaloman 06-12-2017 14:01 2782744

Вот вариант решения, не совсем так, как Вы хотели
Код:

@Echo Off
cls

Set "FileIn=Z:\Soft_In\Тра ля ля.ini"

Set /A Nbeg=0
For /F "usebackq delims=:" %%i In (`"FINDSTR /B /L /I /N /C:":AddParametersSpisok" "%~dpnx0""`) DO Set /A Nbeg=%%i
If %Nbeg% EQU 0 Echo !!! Не найдены параметры для замены &Pause &Exit /B 240
If Not Exist "%FileIn%" Echo !!! Не найден файл "%FileIn%" &Pause &Exit /B 240

>"%FileIn%.Refresh" (For /F "usebackq tokens=1,* delims==" %%i In (`"more +%Nbeg% "%~dpnx0""`) DO (
        If /I "%%i"=="GoTo :Eof" GoTo :Cont
        If Not "%%j"=="" (Echo %%i=%%j)
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])     
))

:Cont
>"%FileIn%.tmp" (For /F "usebackq tokens=1* delims==" %%i In ("%FileIn%") DO (
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])
        If Not "%%j"=="" (FINDSTR /B /I /N /C:"%%i" "%FileIn%.Refresh" >nul 2>nul)||(Echo %%i=%%j)     
))

>"%FileIn%" (For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.tmp""`) DO (
        If "%%j"=="" (
                (Echo %%i)
                For /F "usebackq delims=:" %%n In (`"FINDSTR /B /L /I /N /C:"%%i" "%FileIn%.Refresh"" 2^>nul`) DO Call :NewParameters %%n
        ) Else (
                (Echo %%i=%%j)
        )
        )
        Set /A Log=1
        For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.Refresh""`) DO (
                Call :AddSections "%%i"  "%%j"
        )
)
Del "%FileIn%.tmp" 2>nul
Del "%FileIn%.Refresh" 2>nul

GoTo :Eof

:NewParameters
        For /F "usebackq tokens=1,* delims==" %%a In (`"more +%1 "%FileIn%.Refresh""`) DO (
                If "%%b"=="" GoTo :Eof
                (Echo %%a=%%b)
        )
GoTo :Eof

:AddSections
        If %2=="" (
                Set /A Log=1
                FINDSTR /B /L /I /N /C:%1 "%FileIn%" >nul 2>nul && Set /A Log=0
        )
        If %Log% EQU 1 If %2=="" Echo %~1
        If %Log% EQU 1 If Not %2=="" Echo %~1=%~2
GoTo :Eof

:AddParametersSpisok

[Display]     
bFXAAEnabled=5555550
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100999999999999999999999999
[MAIN]       
fSkyCellRefFadeDistance=600000.0000
[Trees]       
uiMaxSkinnedTreesToRender=2005555
[Water]       
iWaterReflectHeight=10245555
iWaterReflectWidth=1024

GoTo :Eof

Пропишите свой путь к ини-файлу.
В батнике пропишите реальные параметры для замены/вставки между :AddParametersSpisok и GoTo :Eof аналогично моему примеру.
Что не так, как Вам хотелось:
В изменённом ини-файле все изменённые/добавленные строки станут сразу за заголовком секции в том порядке, как Вы их указали в батнике. Я решил (возможно ошибочно - отзовитесь :) ), что это не принципиально.
Если какая-либо секция отсутствует в ини-файле, а в батнике она указана, она будет добавлена в конец ини со всеми параметрами.
Я предполагал (возможно ошибочно), что имена параметров уникальны, то есть в разных секциях не может быть параметров с одинаковыми именами.

Как-то малость громоздко получилось ...

Iska 06-12-2017 14:43 2782751

Цитата:

Цитата megaloman
Я предполагал (возможно ошибочно), что имена параметров уникальны, то есть в разных секциях не может быть параметров с одинаковыми именами. »

Имена параметров должны быть уникальны в пределах раздела, в разных разделах могут и совпадать (это не для данного случая, а так, вообще).

Stalker_AleX333 06-12-2017 15:20 2782765

megaloman, да, это то, что мне нужно. Спасибо.

Только я, наверное, много где накосячил, впихивая эту конструкцию в свой код:

Скрытый текст
Код:

cls
@echo off
:: Копирование измененных настроек игры в SkyrimPrefs.ini
set "FileIn1=%USERPROFILE%\Documents\My Games\Skyrim Special Edition\SkyrimPrefs.ini"
set /a nbeg=0
:: Можно сюда комменты, чтоб понятней было, что здесь происходит?
for /f "usebackq delims=:" %%i in (`"findstr /b /l /i /n /c:":skyrimprefs_parameters_list" "%~dpnx0""`) do set /a nbeg=%%i
>"%FileIn1%.refresh" (for /f "usebackq tokens=*" %%i in (`"more +%Nbeg% "%~dpnx0""`) do (if /i "%%i"=="goto :eof" goto :cont) &Echo %%i)

:: И сюда
:cont
>"%FileIn1%.tmp" (for /f "usebackq tokens=1* delims==" %%i in ("%FileIn1%") do (
        if "%%j"=="" echo %%i
        if not "%%j"=="" (findstr /b /i /n /c:"%%i" "%FileIn3%.refresh" >nul 2>nul)||(echo %%i=%%j)     
))

:: И сюда
>"%FileIn1%" (for /f "usebackq tokens=1,* delims==" %%i in (`"more "%FileIn1%.tmp""`) do (
        if "%%j"=="" (
                echo %%i
                for /f "usebackq delims=:" %%n in (`"findstr /b /l /i /n /c:"%%i" "%FileIn1%.refresh"" 2^>nul`) do call :new_parameters %%n
        ) else (
                (echo %%i=%%j)
        )
        )
        set /a log=1
        for /f "usebackq tokens=1,* delims==" %%i in (`"more "%FileIn1%.refresh""`) do (
                call :add_sections "%%i"  "%%j"
        )
)
del "%FileIn1%.tmp" 2>nul
del "%FileIn1%.refresh" 2>nul

goto :eof

:: И сюда
:new_parameters
        for /f "usebackq tokens=1,* delims==" %%a in (`"more +%1 "%FileIn1%.refresh""`) do (
                if "%%b"=="" goto :eof
                (echo %%a=%%b)
        )
goto :eof

:: И сюда
:add_sections
        if %2=="" (
                set /a log=1
                findstr /b /l /i /n /c:%1 "%FileIn1%" >nul 2>nul && Set /a log=0
        )
        if %log% equ 1 if %2=="" echo %~1
        if %log% equ 1 if not %2=="" echo %~1=%~2
goto :eof

:: Список изменяемых параметров SkyrimPrefs.ini
[Display]
bFXAAEnabled=0
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100
[MAIN]
fSkyCellRefFadeDistance=600000.0000
[Trees]
uiMaxSkinnedTreesToRender=200
[Water]
iWaterReflectHeight=1024
iWaterReflectWidth=1024

:skyrimprefs_parameters_list

:: Копирование отсортированного списка модов
set "FileIn2=Silver Raven mods pack settings\Plugins.txt"
set "BoxOut1=%USERPROFILE%\AppData\Local\Skyrim Special Edition"
if not exist "%BoxOut1%" md "%BoxOut1%"
copy /y "%FileIn2%" "%BoxOut1%\"

:: Копирование файла настроек игры Skyrim.ini
set "FileIn3=Silver Raven mods pack settings\Skyrim.ini"
set "BoxOut2=%USERPROFILE%\Documents\My Games\Skyrim Special Edition"
if not exist "%BoxOut2%" md "%BoxOut2%"
copy /y "%FileIn3%" "%BoxOut2%\"

if exist "%FileIn1%" ( color 07
echo.
echo.
echo ■ SkyrimPrefs.ini успешно отредактирован.
)

if exist "%FileIn2%" ( color 07
echo.
echo.
echo ■ Отсортированный список плагинов успешно скопирован в AppData пользователя.
)

if exist "%FileIn3%" ( color 07
echo.
echo.
echo ■ Skyrim.ini успешно скопирован в папку документов пользователя.
)

if not exist "%FileIn1%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось внести изменения в файл настроек игры.
 echo Запустите лаунчер и произведите настройки, согласно своим предпочтениям. Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

if %nbeg% equ 0 ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Список параметров для SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось изменить файл настроек игры.
 echo Сообщите о данной проблеме автору сборки! Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

if not exist "%FileIn2%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Plugins.txt не найден!
 echo.
 echo Не удалось скопировать отсортированный список плагинов.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

if not exist "%FileIn3%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Skyrim.ini не найден!
 echo.
 echo Не удалось скопировать файл скрытых настроек игры.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

@echo.
@echo.
pause
exit
:: goto main_menu



Не выводятся мои сообщения и при отсутствии файла SkyrimPrefs.ini, cmd-шник создает таковой и прописывает в тушку все свое содержимое.

megaloman 06-12-2017 19:18 2782801

Комментарии по тексту скрипта
Код:

@Echo Off
cls

Set "FileIn=Z:\Soft_In\Тра ля ля.ini"

rem Контролируем наличие в батнике данных для замены/обновления
Set /A Nbeg=0
For /F "usebackq delims=:" %%i In (`"FINDSTR /B /L /I /N /C:":AddParametersSpisok" "%~dpnx0""`) DO Set /A Nbeg=%%i
If %Nbeg% EQU 0 Echo !!! Не найдены параметры для замены &Pause &Exit /B 240

rem Контролируем наличие исходного ини-файла
If Not Exist "%FileIn%" Echo !!! Не найден файл "%FileIn%" &Pause &Exit /B 240

rem Организуем отдельный Refresh файл, куда помещаем из батника данные для корректировки исходного ини-файла
>"%FileIn%.Refresh" (For /F "usebackq tokens=1,* delims==" %%i In (`"more +%Nbeg% "%~dpnx0""`) DO (
        If /I "%%i"=="GoTo :Eof" GoTo :Cont
        If Not "%%j"=="" (Echo %%i=%%j)
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])     
))

:Cont

rem Организуем промежуточный tmp файл из исходного, в котором удалены все упомянутые для корректировки параметры
>"%FileIn%.tmp" (For /F "usebackq tokens=1* delims==" %%i In ("%FileIn%") DO (
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])
        If Not "%%j"=="" (FINDSTR /B /I /N /C:"%%i" "%FileIn%.Refresh" >nul 2>nul)||(Echo %%i=%%j)     
))

rem Получаем боевой ини-файл с именем исходного. Берём tmp-файл,
rem Последовательно анализируем наличие секции в Refresh файле, если она там присутствует, забираем из Refresh файла всю секцию
rem Дописываем далее в эту секцию всё что осталось в tmp-файле из этой секции
rem Просматриваем Refresh-файл, если не находим какой-либо помянутой там секции в боевом файле, дописываем эту секцию в конец

>"%FileIn%" (For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.tmp""`) DO (
        If "%%j"=="" (
                Echo %%i
                For /F "usebackq delims=:" %%n In (`"FINDSTR /B /L /I /N /C:"%%i" "%FileIn%.Refresh"" 2^>nul`) DO Call :NewParameters %%n
        ) Else (
                (Echo %%i=%%j)
        )
        )
        Set /A Log=1
        For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.Refresh""`) DO (
                Call :AddSections "%%i"  "%%j"
        )
)
rem Удаляем промежуточные файлы
Del "%FileIn%.tmp" 2>nul
Del "%FileIn%.Refresh" 2>nul

GoTo :Eof

rem Забираем секцию из Refresh файла
:NewParameters
        For /F "usebackq tokens=1,* delims==" %%a In (`"more +%1 "%FileIn%.Refresh""`) DO (
                If "%%b"=="" GoTo :Eof
                (Echo %%a=%%b)
        )
GoTo :Eof

rem Добавляем в конечный файл отсутствующие в нём секции из Refresh файла
:AddSections
        If %2=="" (
                Set /A Log=1
                FINDSTR /B /L /I /N /C:%1 "%FileIn%" >nul 2>nul && Set /A Log=0
        )
        If %Log% EQU 1 If %2=="" Echo %~1
        If %Log% EQU 1 If Not %2=="" Echo %~1=%~2
GoTo :Eof

:AddParametersSpisok

[Display]
bFXAAEnabled=01234567890
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
kuku=868768686
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100
[MAIN]
fSkyCellRefFadeDistance=600000.0000
[Trees]
uiMaxSkinnedTreesToRender=200
[Water]
iWaterReflectHeight=1024
iWaterReflectWidth=1024

GoTo :Eof

Есть одна неприятная тонкость: в конце строк, особенно в названии секций, не должно быть пробелов, которые визуально могут не восприниматься. Я доработал скрипт, чтобы этого избежать.
Я не узнаю своего скрипта, трудно понять, в чём загвоздка
Старый анекдот.
- Звонок в техподдержку: у меня не работает компьютер.
- Следует совет: а попробуйте устранить неисправность сами.
-Возмущенный клиент: а как директор фирмы смотрит на то, что вы уклоняетесь от работы?
- ответ: положительно, обычно после действий клиента доходы фирмы значительно вырастают.

Stalker_AleX333 06-12-2017 20:40 2782812

Отдельно от всего код полностью рабочий. Остался только один вопрос: как перескочить с него на другой в одном cmd-шнике?

И как он останавливается? goto :eof в самом конце его как-будто, зацикливает.

Оставил все как есть, только подкрепил внизу свое барахло, и перенес информационные сообщения:

Скрытый текст
Код:

cls
@echo off
set "FileIn1=%USERPROFILE%\Documents\My Games\Skyrim Special Edition\SkyrimPrefs.ini"
:: Контролируем наличие в батнике данных для замены/обновления
Set /A Nbeg=0
For /F "usebackq delims=:" %%i In (`"FINDSTR /B /L /I /N /C:":skyrimprefs_parameters_list" "%~dpnx0""`) DO Set /A Nbeg=%%i

:: Перемещено вниз, но не работает
::If %Nbeg% EQU 0 Echo !!! Не найдены параметры для замены &Pause &Exit /B 240

:: Перемещено вниз, но не работает
::If Not Exist "%FileIn1%" Echo !!! Не найден файл "%FileIn1%" &Pause &Exit /B 240

:: Организуем отдельный Refresh файл, куда помещаем из батника данные для корректировки исходного ини-файла
>"%FileIn1%.Refresh" (For /F "usebackq tokens=*" %%i In (`"more +%Nbeg% "%~dpnx0""`) DO (If /I "%%i"=="GoTo :Eof" GoTo :Cont) &Echo %%i)
:Cont

:: Организуем промежуточный tmp файл из исходного, в котором удалены все упомянутые для корректировки параметры
>"%FileIn1%.tmp" (For /F "usebackq tokens=1* delims==" %%i In ("%FileIn1%") DO (
        If "%%j"=="" Echo %%i
        If Not "%%j"=="" (FINDSTR /B /I /N /C:"%%i" "%FileIn1%.Refresh" >nul 2>nul)||(Echo %%i=%%j)     
))

:: Получаем боевой ини-файл с именем исходного. Берём tmp-файл,
:: Последовательно анализируем наличие секции в Refresh файле, если она там присутствует, забираем из Refresh файла всю секцию
:: Дописываем далее в эту секцию всё что осталось в tmp-файле из этой секции
:: Просматриваем Refresh-файл, если не находим какой-либо помянутой там секции в боевом файле, дописываем эту секцию в конец

>"%FileIn1%" (For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn1%.tmp""`) DO (
        If "%%j"=="" (
                Echo %%i
                For /F "usebackq delims=:" %%n In (`"FINDSTR /B /L /I /N /C:"%%i" "%FileIn1%.Refresh"" 2^>nul`) DO Call :NewParameters %%n
        ) Else (
                (Echo %%i=%%j)
        )
        )
        Set /A Log=1
        For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn1%.Refresh""`) DO (
                Call :AddSections "%%i"  "%%j"
        )
)
:: Удаляем промежуточные файлы
Del "%FileIn1%.tmp" 2>nul
Del "%FileIn1%.Refresh" 2>nul

GoTo :Eof

:: Забираем секцию из Refresh файла
:NewParameters
        For /F "usebackq tokens=1,* delims==" %%a In (`"more +%1 "%FileIn1%.Refresh""`) DO (
                If "%%b"=="" GoTo :Eof
                (Echo %%a=%%b)
        )
GoTo :Eof

:: Добавляем в конечный файл отсутствующие в нём секции из Refresh файла
:AddSections
        If %2=="" (
                Set /A Log=1
                FINDSTR /B /L /I /N /C:%1 "%FileIn1%" >nul 2>nul && Set /A Log=0
        )
        If %Log% EQU 1 If %2=="" Echo %~1
        If %Log% EQU 1 If Not %2=="" Echo %~1=%~2
GoTo :Eof

:skyrimprefs_parameters_list
[Display]
bFXAAEnabled=0
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100
[MAIN]
fSkyCellRefFadeDistance=600000.0000
[Trees]
uiMaxSkinnedTreesToRender=200
[Water]
iWaterReflectHeight=1024
iWaterReflectWidth=1024
GoTo :Eof

:::::::::::::::::::::::::::::::::::::::::::::::::::

:: Копирование отсортированного списка модов
set "FileIn2=Silver Raven mods pack settings\Plugins.txt"
set "BoxOut1=%USERPROFILE%\AppData\Local\Skyrim Special Edition"
if not exist "%BoxOut1%" md "%BoxOut1%"
copy /y "%FileIn2%" "%BoxOut1%\"

:: Копирование файла настроек игры Skyrim.ini
set "FileIn3=Silver Raven mods pack settings\Skyrim.ini"
set "BoxOut2=%USERPROFILE%\Documents\My Games\Skyrim Special Edition"
if not exist "%BoxOut2%" md "%BoxOut2%"
copy /y "%FileIn3%" "%BoxOut2%\"

if exist "%FileIn1%" ( color 07
echo.
echo.
echo ■ SkyrimPrefs.ini успешно отредактирован.
)

if exist "%FileIn2%" ( color 07
echo.
echo.
echo ■ Отсортированный список плагинов успешно скопирован в AppData пользователя.
)

if exist "%FileIn3%" ( color 07
echo.
echo.
echo ■ Skyrim.ini успешно скопирован в папку документов пользователя.
)

if not exist "%FileIn1%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось внести изменения в файл настроек игры.
 echo Запустите лаунчер и произведите настройки, согласно своим предпочтениям. Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

if %Nbeg% EQU 0 ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Список параметров для SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось внести изменения в файл настроек игры.
 echo Сообщите о данной проблеме автору сборки! Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

if not exist "%FileIn2%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Plugins.txt не найден!
 echo.
 echo Не удалось скопировать отсортированный список плагинов.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

if not exist "%FileIn3%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Skyrim.ini не найден!
 echo.
 echo Не удалось скопировать файл скрытых настроек игры.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

@echo.
@echo.
pause
exit


megaloman 06-12-2017 20:51 2782814

Stalker_AleX333, Возмите доработаный вариант скрипта, он надёжнее. Я подчеркнул доработки.
GoTo :Eof ничего не зацикливает. Это один из способов указать на окончание завершение программной единицы: главной части и каждой подпрограммы. По моему убеждению в Вашем коде всё, что ниже ::::::::::::::::::::::::::::::::::::::::::::::::::: работать не будет. Скрипт исполняется последовательно, и после GoTo :Eof в тот кусок скрипта попасть невозможно, Вы на него никак не ссылаетесь.
Так можно совместить мой код и Ваш (я его не изучал, что там делается, не смотрел). Не понимаю, почему Вы убираете контроль файла на наличие и наличие обновлений.
Код:

@Echo Off
cls

Call :ModyIniFile "Z:\Soft_In\Тра л2я ля.ini"
If Not %ErrorLevel%==0 GoTo :Eof

rem Далее свой кусок скрипта


GoTo :Eof

:ModyIniFile

Set "FileIn=%~1"

Set /A Nbeg=0
For /F "usebackq delims=:" %%i In (`"FINDSTR /B /L /I /N /C:":AddParametersSpisok" "%~dpnx0""`) DO Set /A Nbeg=%%i
If %Nbeg% EQU 0 Echo !!! Не найдены параметры для замены &Pause &Exit /B 240
If Not Exist "%FileIn%" Echo !!! Не найден файл "%FileIn%" &Pause &Exit /B 240

>"%FileIn%.Refresh" (For /F "usebackq tokens=1,* delims==" %%i In (`"more +%Nbeg% "%~dpnx0""`) DO (
        If /I "%%i"=="GoTo :Eof" GoTo :Cont
        If Not "%%j"=="" (Echo %%i=%%j)
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])     
))

:Cont
>"%FileIn%.tmp" (For /F "usebackq tokens=1* delims==" %%i In ("%FileIn%") DO (
        If "%%j"=="" For /F "tokens=1 delims=]" %%s In ("%%i") DO (Echo %%s])
        If Not "%%j"=="" (FINDSTR /B /I /N /C:"%%i" "%FileIn%.Refresh" >nul 2>nul)||(Echo %%i=%%j)     
))

>"%FileIn%" (For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.tmp""`) DO (
        If "%%j"=="" (
                (Echo %%i)
                For /F "usebackq delims=:" %%n In (`"FINDSTR /B /L /I /N /C:"%%i" "%FileIn%.Refresh"" 2^>nul`) DO Call :NewParameters %%n
        ) Else (
                (Echo %%i=%%j)
        )
        )
        Set /A Log=1
        For /F "usebackq tokens=1,* delims==" %%i In (`"more "%FileIn%.Refresh""`) DO (
                Call :AddSections "%%i"  "%%j"
        )
)
Del "%FileIn%.tmp" 2>nul
Del "%FileIn%.Refresh" 2>nul

Exit /B 0

:NewParameters
        For /F "usebackq tokens=1,* delims==" %%a In (`"more +%1 "%FileIn%.Refresh""`) DO (
                If "%%b"=="" GoTo :Eof
                (Echo %%a=%%b)
        )
GoTo :Eof

:AddSections
        If %2=="" (
                Set /A Log=1
                FINDSTR /B /L /I /N /C:%1 "%FileIn%" >nul 2>nul && Set /A Log=0
        )
        If %Log% EQU 1 If %2=="" Echo %~1
        If %Log% EQU 1 If Not %2=="" Echo %~1=%~2
GoTo :Eof

:AddParametersSpisok

[Display]     
bFXAAEnabled=djabmnsbmnabm5555550
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100999999999999999999999999
[MAIN]       
fSkyCellRefFadeDistance=600000.0000
[Trees]       
uiMaxSkinnedTreesToRender=2005555
[Water]       
iWaterReflectHeight=10245555
iWaterReflectWidth=1024
GoTo :Eof


Stalker_AleX333 07-12-2017 14:25 2782975

megaloman, так все работает, но после прожатия "продолжить" вываливается ошибка об отсутствии ini файла, хотя он есть и на тот момент уже отредактирован:

Скрытый текст
Код:

cls
:: Копирование отсортированного списка модов
set "FileIn1=Silver Raven mods pack settings\Plugins.txt"
set "BoxOut1=%USERPROFILE%\AppData\Local\Skyrim Special Edition"
if not exist "%BoxOut1%" md "%BoxOut1%"
copy /y "%FileIn1%" "%BoxOut1%\"

:: Копирование файла настроек игры Skyrim.ini
set "FileIn2=Silver Raven mods pack settings\Skyrim.ini"
set "BoxOut2=%USERPROFILE%\Documents\My Games\Skyrim Special Edition"
if not exist "%BoxOut2%" md "%BoxOut2%"
copy /y "%FileIn2%" "%BoxOut2%\"

if exist "%FileIn1%" ( color 07
 echo.
 echo.
 echo ■ Отсортированный список плагинов успешно скопирован в AppData пользователя.
)

if exist "%FileIn2%" ( color 07
 echo.
 echo.
 echo ■ Skyrim.ini успешно скопирован в папку документов пользователя.
)

if not exist "%FileIn1%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Plugins.txt не найден!
 echo.
 echo Не удалось скопировать отсортированный список плагинов.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

if not exist "%FileIn2%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл Skyrim.ini не найден!
 echo.
 echo Не удалось скопировать файл скрытых настроек игры.
 echo Извлеките папку Silver Raven mods pack settings из установочных архивов со сборкой в папку с игрой вручную и перезапустите панель управления. Убедитесь, что антивирусное ПО не блокирует ее работу и у вас достаточно прав на доступ к папкам пользователя.
)

:: Копирование измененных настроек игры в SkyrimPrefs.ini
call :skyrimprefs_ini_file "%USERPROFILE%\Documents\My Games\Skyrim Special Edition\SkyrimPrefs.ini"
if not %ErrorLevel%==0 goto :eof

:skyrimprefs_ini_file
set "FileIn3=%~1"
set /a Nbeg=0
:: Контролируем наличие в cmd(exe)-шнике данных для замены
for /f "usebackq delims=:" %%i in (`"findstr /b /l /i /n /c:":skyrimprefs_parameters_list" "%~dpnx0""`) do set /a nbeg=%%i

if exist "%FileIn3%" ( color 07
 echo.
 echo.
 echo ■ SkyrimPrefs.ini успешно отредактирован.
)

if not exist "%FileIn3%" ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Файл SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось внести изменения в файл настроек игры.
 echo Запустите лаунчер и произведите настройки, согласно своим предпочтениям. Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

if %Nbeg% equ 0 ( color 0c
 echo.
 echo.
 echo *ОШИБКА! Список параметров для SkyrimPrefs.ini не найден!
 echo.
 echo Не удалось внести изменения в файл настроек игры.
 echo Сообщите о данной проблеме автору сборки! Убедитесь, что антивирусное ПО не блокирует работу панели управления и у вас достаточно прав на доступ к папкам пользователя.
)

@echo.
@echo.
::::::::::::::::::::: После прожатия этой паузы вываливается ложная ошибка. Что-то она ломает:::::::::::::::::::::::::::::::
pause
:::::::::::::::::::::
:: goto main_menu

:: Создаем отдельный Refresh файл, куда помещаем данные для корректировки исходного ini файла
>"%FileIn3%.refresh" (for /f "usebackq tokens=*" %%i in (`"more +%nbeg% "%~dpnx0""`) do (if /i "%%i"=="goto :eof" goto :cont) &echo %%i)

:cont
:: Создаем временный файл из исходного, в котором удалены все упомянутые для корректировки секции
>"%FileIn3%.tmp" (for /f "usebackq tokens=1* delims==" %%i in ("%FileIn3%") do (
        if "%%j"=="" echo %%i
        if not "%%j"=="" (findstr /b /i /n /c:"%%i" "%FileIn3%.refresh" >nul 2>nul)||(echo %%i=%%j)
))

:: Получаем "боевой" ini файл с именем исходного
:: Берём временный файл, последовательно анализируем наличие секций в Refresh файле, если они там присутствуют, забираем их из Refresh файла
:: Дописываем в эту секцию всё, что осталось во временном файле из этой секции
:: Просматриваем Refresh-файл, если не находим какой-либо упомянутой там секции в боевом файле, дописываем ее в конец
>"%FileIn3%" (for /f "usebackq tokens=1,* delims==" %%i in (`"more "%FileIn3%.tmp""`) do (
        if "%%j"=="" (
                echo %%i
                for /f "usebackq delims=:" %%n in (`"findstr /b /l /i /n /c:"%%i" "%FileIn3%.refresh"" 2^>nul`) do call :new_parameters %%n
        ) else (
                (echo %%i=%%j)
        )
        )
        set /a log=1
        for /f "usebackq tokens=1,* delims==" %%i in (`"more "%FileIn3%.refresh""`) do (
                call :add_sections "%%i"  "%%j"
        )
)
:: Удаляем временные файлы
del "%FileIn3%.tmp" 2>nul
del "%FileIn3%.refresh" 2>nul

exit /b 0

:: Забираем секцию из Refresh файла
:new_parameters
        for /f "usebackq tokens=1,* delims==" %%a in (`"more +%1 "%FileIn3%.refresh""`) do (
                if "%%b"=="" goto :eof
                (echo %%a=%%b)
        )
goto :eof

:: Добавляем в конечный файл отсутствующие в нём секции из Refresh файла
:add_sections
        if %2=="" (
                set /a log=1
                findstr /b /l /i /n /c:%1 "%FileIn3%" >nul 2>nul && Set /a log=0
        )
        if %log% equ 1 if %2=="" echo %~1
        if %log% equ 1 if not %2=="" echo %~1=%~2
goto :eof

:: Список изменяемых секций в SkyrimPrefs.ini
:skyrimprefs_parameters_list
[Display]
bFXAAEnabled=0
fTreesMidLODSwitchDist=8192.000
fMeshLODLevel2FadeTreeDistance=4096.000
fMeshLODLevel1FadeTreeDistance=6144.000
iMaxDecalsPerFrame=250
iMaxSkinDecalsPerFrame=100
[MAIN]
fSkyCellRefFadeDistance=600000.0000
[Trees]
uiMaxSkinnedTreesToRender=200
[Water]
iWaterReflectHeight=1024
iWaterReflectWidth=1024
goto :eof



P.S. На сообщения в личке можно забить, они устарели. Из полезного, там разве что весь остальной код, который я сюда не прикреплял.

megaloman 07-12-2017 15:09 2782990

Stalker_AleX333, Извините, не берусь искать ошибки в чужом большом коде, особенно если я не понимаю логику постановки задачи, а восстанавливать её из кода - трудоёмкая и неблагодарная работа.
Цитата:

Цитата Iska
Ждите коллег, может помогут. »


alpap 07-12-2017 15:27 2782997

Stalker_AleX333,
я наверное понимаю о чем вы. bat не будет работать в интерактивном режиме, выполнив задачу по изменению ini, bat должен завершить работу. Значит bat для изменения ini должен быть свой (отдельный), а запускать его можно из основного, например:
Код:

::код основного
call "Путь к bat для изменения ini"
::код основного далее


Stalker_AleX333 07-12-2017 16:10 2783006

alpap, проблема в том, что не могу юзать два разных cmd-шника. Только один, упакованный в exe конвертером. Таковы условия.

А возможно, каждый раз создавать временный cmd-шник из основного, с помещением туда нужного кода, а после выполнения удаляя его?

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

alpap 07-12-2017 16:14 2783008

Цитата:

Цитата Stalker_AleX333
упакованный в exe конвертером »

конвертер без проблем упакует все что надо, вкладка ВКЛЮЧИТЬ-ДОБАВИТЬ

Iska 07-12-2017 16:41 2783013

Цитата:

Цитата Stalker_AleX333
не могу юзать два разных cmd-шника. Только один, упакованный в exe конвертером. Таковы условия. »

Что-то мне подсказывает, что это надуманные условия. Если же речь идёт о том, что вот только исполняемый файл и никак иначе — берёте с++ и gcc, и пользуете унаследованные функции GetPrivateProfileString()/WritePrivateProfileString().

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Stalker_AleX333 07-12-2017 16:42 2783014

alpap, Попробовал. При запуске exe-шника выдает ошибку, что мол не могу создать файл, бла-бла-бла.cmd. Продолжить работу?

Цитата:

Цитата Iska
Что-то мне подсказывает, что это надуманные условия. »

Отчасти. Но это не мои условия. Так что увы и ах...

alpap 07-12-2017 16:59 2783023

Stalker_AleX333,
я тоже не горю желанием разбирать ваш многоэтажный код и исходя из всего увиденного код надо делать на PowerShell или Autoit, тогда будет и удобно что-то менять в интерактивном режиме, можно и красочно сделать - выносное меню-окно и выпадающие списки, а cmd пусть тихо покурит в сторонке, не его это задачи.

Stalker_AleX333 07-12-2017 17:43 2783038

alpap, да, надо бы попробовать на PowerShell. А не насиловать несчастные cmd и bat файлы. Благодарю всех за помощь. Тему закрываю.

Iska 07-12-2017 17:54 2783042

Stalker_AleX333, коль Вам всё равно исполняемый файл нужо́́н — лучше попробуйте AutoIt, там хотя бы встроенные функции для работы с ini есть.


Время: 01:19.

Время: 01:19.
© OSzone.net 2001-