Reputation: 25938
I am attempting to replace a line in a file.
My Problem: I can never find the line I am looking for in a file. My function finds the line I want to replace but doesn't correctly identify it as the one I want to replace or maybe it fails to open the file(the path to the file is correct).
If you test the my function with the following simple textfile it still fails:
abc
test
data
Can you help me to get my function to correctly replace a line in a file?
# usage that fails to work
Push "C:\Users\blah\Desktop"
Push "test.txt"
Push "abc"
Push "def"
Call ReplaceLineInFile
Function ReplaceLineInFile
# T-3 = nDir
# T-2 = nFile
# T-1 = targetLine
# TOP = replaceLine # TOP is top of stack
# $4 = tempName
# $5 = numTargetLinesFound
Pop $3 # replaceLine
Pop $2 # targetLine
Pop $1 # nFile
Pop $0 # nDir
StrCpy $1 "$0\$1" # create the string 'C:\users\blah\mytext.txt'
IntOp $5 0 + 0
MessageBox MB_OK "ReplaceLineInFile: dir: $0$\r$\nfile: $1$\r$\ntarget: $2$\r$\nreplace: $3"
ClearErrors
FileOpen $8 $1 "r" ; open target file for reading
GetTempFileName $4 ; get new temp file name
FileOpen $7 $4 "w" ; open temp file for writing
loop:
FileRead $8 $6 ; read line from target file
IfErrors done ; check if end of file reached
MessageBox MB_OK "Line: $6$\r$\nTarg: $2"
StrCmp $6 "$2$\r$\n" 0 +3 ; compare line with search string with CR/LF
StrCpy $6 "$3$\r$\n" ; change line
IntOp $5 $5 + 1
StrCmp $6 "$2" 0 +3 ; compare line with search string without CR/LF (at the end of the file)
StrCpy $6 "$3" ; change line
IntOp $5 $5 + 1
FileWrite $7 $6 ; write changed or unchanged line to temp file
Goto loop
done:
FileClose $8 ; close target file
FileClose $7 ; close temp file
Delete $1 ; delete target file
CopyFiles /SILENT $4 $1 ; copy temp file to target file
Delete $4 ; delete temp file
MessageBox MB_OK "Targets found: $5"
FunctionEnd
Upvotes: 2
Views: 2011
Reputation: 5456
You should check LineFind macro for NSIS: http://nsis.sourceforge.net/LineFind
To replace lines in files you can try to use:
Name "Text Replacer"
OutFile "TextReplacer.exe"
;[DEFINES] You define String To Find and String To Replace
!include "TextFunc.nsh"
!insertmacro LineFind
!include "Sections.nsh"
!define STRTOFIND "BaseLine1: TextThatShouldBeChanged"
!define STRTOREPL "BaseLine1: TextHasBeenCHANGED!!!"
!define STRTOFIND2 "[BaseLine2=TextThatShouldBeChanged;"
!define STRTOREPL2 "[BaseLine2=TextCHANGED!!!;"
;[Functions] You create Line Replace Functions for each line
Function LineFindCallback
StrLen $0 "${STRTOFIND}"
StrCpy $1 "$R9" $0
StrCmp $1 "${STRTOFIND}" 0 End
StrCpy $R9 "${STRTOREPL}$\r$\n"
End:
Push $0
FunctionEnd
Function LineFindCallback2
StrLen $0 "${STRTOFIND2}"
StrCpy $1 "$R9" $0
StrCmp $1 "${STRTOFIND2}" 0 End
StrCpy $R9 "${STRTOREPL2}$\r$\n"
End:
Push $0
FunctionEnd
;[Sections] You call function for specific line in specific file
;Input and Output file can be same or different
;If Output file name is different (new file is created)
;then every next LineFind call should take Previous Output file as Input file
Section "Replace 1" Section1
SectionIn 1 +2
${LineFind} "$EXEDIR\FILE.ini" "$EXEDIR\FILE.ini" "1:-1" "LineFindCallback"
IfErrors 0 +2
MessageBox MB_OK "Error"
${LineFind} "$EXEDIR\FILE.ini" "$EXEDIR\FILE.ini" "1:-1" "LineFindCallback2"
IfErrors 0 +2
MessageBox MB_OK "Error"
SectionEnd
Create FILE.ini
containing and keep it in same folder which you will have TextReplacer.exe
:
This is File.ini file
That line will not be changed
BaseLine1: TextThatShouldBeChanged
This line=is just a dummy line
[BaseLine2=TextThatShouldBeChanged;
File.ini end
Upvotes: 3