-1

Hello and firstly I would like to apologize for this post if it was already answered before. I spent the last 4 hours searching Stackoverflow and Google.

I have a gamesettings.ini file I would like to edit via batch file. I need to perform this over many PCs, so I would like to keep the other settings besides 2 lines in the file.

The two lines im trying to change are:

CustomVoiceChatInputDevice=Default Input
CustomVoiceChatOutputDevice=Default Output

I tried a few batch scripts I found on Stackoverflow, but they only work if I define the full line. Since every user has different options set, i need the script to just take the start of the line. Just "CustomVoiceChatInputDevice" for example.

Here's an example code I used, thanks to @jsanchez. This script doesn't work unless I type out the whole line:

Thank you for your time!!

@echo off
::Use the path from whence the script was executed as
::the Current Working Directory
set CWD=C:\

::***BEGIN MODIFY BLOCK***
::The variables below should be modified to the
::files to be changed and the strings to find/replace
::Include trailing backslash in _FilePath
set _FilePath=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient\
set _FileName=GameUserSettings.ini
::_WrkFile is the file on which the script will make
::modifications.
set _WrkFile=GameUserSettings.bak
set OldStr="CustomVoiceChatInputDevice"
set NewStr="CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"

::***END MODIFY BLOCK***

::Set a variable which is used by the
::search and replace section to let us
::know if the string to be modified was
::found or not.
set _Found=Not found

SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION

if not exist "%_FilePath%%_FileName%" goto :NotFound

::If a backup file exists, delete it
if exist "%_FilePath%%_WrkFile%" (
    echo Deleting "%_FilePath%%_WrkFile%" 
    del "%_FilePath%%_WrkFile%" >nul 2>&1
    )

echo.
echo Backing up "%_FilePath%%_FileName%"...
copy "%_FilePath%%_FileName%" "%_FilePath%%_WrkFile%" /v

::Delete the original file. No worries, we got a backup.
if exist "%_FilePath%%_FileName%" del "%_FilePath%%_FileName%"
echo.
echo Searching for %OldStr% string...
echo.
for /f "usebackq tokens=*" %%a in ("%_FilePath%%_WrkFile%") do (
    set _LineChk=%%a
    if "!_LineChk!"==%OldStr% (
        SET _Found=Found 
        SET NewStr=!NewStr:^"=! 
        echo !NewStr!
        ) else (echo %%a)
        )>>"%_FilePath%%_FileName%" 2>&1

::If we didn't find the string, rename the backup file to the original file name
::Otherwise, delete the _WorkFile as we re-created the original file when the
::string was found and replaced.
if /i "!_Found!"=="Not found" (echo !_Found! && del "%_FilePath%%_FileName%" && ren "%_FilePath%%_WrkFile%" %_FileName%) else (echo !_Found! && del "%_FilePath%%_WrkFile%")
goto :exit

:NotFound
echo.
echo File "%_FilePath%%_FileName%" missing. 
echo Cannot continue...
echo.
:: Pause script for approx. 10 seconds...
PING 127.0.0.1 -n 11 > NUL 2>&1
goto :Exit

:Exit
exit /b
Neo Storm
  • 13
  • 2

2 Answers2

2

Each setting within your .ini file identifies the name of the setting. So the order of the lines should not may not matter.

If the line order is meaningless, then all you need do is use FINDSTR /V to remove the old values, and then simply append the new values. In the script below I modify both values at the same time.

@echo off
setlocal enableDelayedExpansion

set "iniLoc=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient"
set "iniFile=%iniLoc%\GameUserSettings.ini"
set "iniBackup=%iniLoc%\GameUserSettings.bak"
set "CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"
set "CustomVoiceChatOutputDevice=Some new value"

>"%iniFile%.new" (
  findstr /vb "CustomVoiceChatInputDevice= CustomVoiceChatOutputDevice=" "%iniFile%"
  echo CustomVoiceChatInputDevice=!CustomVoiceChatInputDevice!
  echo CustomVoiceChatOutputDevice=!CustomVoiceChatOutputDevice!
)
copy "%iniFile%" "%iniBackup%"
ren "%iniFile%.new" *.

It would be slightly faster to create the backup file via rename instead of copy, but then there would be a brief moment where the ini file does not exist.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • 1
    Most *.ini files contain sections, i.e. `[Section Name]` and in this case it does matter where the lines starting with `CustomVoiceChatInputDevice=` and with `CustomVoiceChatOutputDevice=` are in the file. Unfortunately original poster has not written anything about content of INI file to modify. – Mofi Oct 10 '18 at 07:39
  • @Mofi - For no good reason, I was envisioning a home-grown game that the OP had developed, and imagined that the order did not matter. But you raise a good point, it is more likely a commercial game where the line order could matter. – dbenham Oct 10 '18 at 12:47
0

Windows command processor is not designed for editing text files, it is designed for running commands and applications.

But this text file editing/replacing task can be nevertheless done with cmd.exe (very slow):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileName=%LOCALAPPDATA%\RedDeadGame\Saved\Config\WindowsClient\GameUserSettings.ini"
set "TempFile=%TEMP%\%~n0.tmp"
if not exist "%FileName%" goto EndBatch

del "%TempFile%" 2>nul

for /F delims^=^ eol^= %%A in ('%SystemRoot%\System32\findstr.exe /N "^" "%FileName%"') do (
    set "Line=%%A"
    setlocal EnableDelayedExpansion
    if not "!Line:CustomVoiceChatInputDevice=!" == "!Line!" (
        echo CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game^)
    ) else if not "!Line:CustomVoiceChatOutputDevice=!" == "!Line!" (
        echo CustomVoiceChatOutputDevice=Line (Astro MixAmp Pro Game^)
    ) else echo(!Line:*:=!
    endlocal
) >>"%TempFile%"

rem Is the temporary file not binary equal the existing INI file, then move
rem the temporary file over existing INI file and delete the temporary file
rem if that fails like on INI file currently opened by an application with
rem no shared write access. Delete the temporary file if it is binary equal
rem the existing INI file because of nothing really changed.

%SystemRoot%\System32\fc.exe /B "%TempFile%" "%FileName%" >nul
if errorlevel 1 (
    move /Y "%TempFile%" "%FileName%"
    if errorlevel 1 del "%TempFile%"
) else del "%TempFile%"

:EndBatch
endlocal

See the answer on How to read and print contents of text file line by line? for an explanation of the FOR loop.

Please note the caret character ^ left to ) in the two lines to output. A closing parenthesis outside a double quoted argument string must be escaped here with ^ as otherwise ) would be interpreted by Windows command processor as end of command block and not as literal character to output by command ECHO. Other characters with special meaning for cmd.exe on parsing a command line or an entire command block like &|<> must be also escaped with ^ on ECHO command lines.

Please take also a look on Wikipedia article about Windows Environment Variables. It is highly recommended to use the right predefined environment variables for folder paths like local application data folder.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /? ... explains %~n0 ... batch file name without path and file extension.
  • del /?
  • echo /?
  • endlocal /?
  • fc /?
  • findstr /?
  • for /?
  • if /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?
Mofi
  • 46,139
  • 17
  • 80
  • 143