Archive: Problem with DeleteINISec


Problem with DeleteINISec
  Hi,

I seem to have a problem with DeleteINISec: I call that command in my function and then add the deleted section back in (with some modifications), at least that's the plan. But in reality, the INI file is empty on every other run of the installer, even though the details view shows $R0 having the correct value.

I can't use the normal INI functions, because I'm modifying wininit.ini.

If anyone can give me some hints, that would be very nice. Maybe I'm doing something obviously wrong, this is my first more complicated function for NSIS. (I'm using NSIS 2.0b2.)

Here's the function:


;
; AddToWininit - adds lines to the [Rename] section of wininit.ini
;
; Expects string with new lines on top of stack
; Returns nothing, error flag will be set on failure
;
; Make sure new lines end with "$\r$\n"
;
Function AddToWininit
Exch $R0 ; lines
Push $R1 ; file handle
Push $R2 ; read buffer
Push $R3 ; compare buffer

ClearErrors
IfFileExists "$WINDIR\wininit.ini" 0 WRITE
FileOpen $R1 "$WINDIR\wininit.ini" "r"
IfErrors SAFE_RETURN

SECTION_LOOP:
FileRead $R1 $R2
IfErrors READ_DONE
Push $R2
Call TrimNewlines
Pop $R2
StrCmp $R2 "[Rename]" 0 SECTION_LOOP

READ_LOOP:
FileRead $R1 $R2
IfErrors READ_DONE
Push $R2
Call TrimNewlines
Pop $R2
StrCmp $R2 "" READ_LOOP
StrCpy $R3 $R2 1
StrCmp $R3 "[" READ_DONE
StrCpy $R0 "$R0$R2$\r$\n"
Goto READ_LOOP

READ_DONE:
FileClose $R1
DeleteINISec "$WINDIR\wininit.ini" "Rename"
ClearErrors

WRITE:
FileOpen $R1 "$WINDIR\wininit.ini" "a"
IfErrors SAFE_RETURN
FileSeek $R1 0 END
FileWrite $R1 "$\r$\n[Rename]$\r$\n"
DetailPrint $R0
FileWrite $R1 $R0
FileClose $R1

SAFE_RETURN:
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd


READ_DONE:
FileClose $R1
DeleteINISec "$WINDIR\wininit.ini" "Rename"
ClearErrors

You close $R1 and you trying to read it again, maybe:


READ_DONE:
DeleteINISec "$WINDIR\wininit.ini" "Rename"
FileClose $R1
ClearErrors


WRITE:

FileOpen $R1 "$WINDIR\wininit.ini" "a"
IfErrors SAFE_RETURN
FileSeek $R1 0 END
>
Replace this above by this below:


WRITE:

FileOpen $R1 "$WINDIR\wininit.ini" "w"
IfErrors SAFE_RETURN
FileSeek $R1 0 END
>
Because when you append is:

Quote from documentation (Chapter4.html)

opened for both read and write, contents preserved
Contents preserved? So can only read, because the contents are preserved. So use the "w" for write.

Originally posted by Dark Boy
You close $R1 and you trying to read it again, maybe:
DeleteINISec doesn't operate on my file handle, I'm pretty sure I have to close it so DeleteINISec can write to the file.

Originally posted by deguix
Contents preserved? So can only read, because the contents are preserved. So use the "w" for write.
No, I quote from the documentation: "a" (append, meaning opened for both read and write, contents preserved)

There's a slim chance that there are other sections in wininit.ini, that's why I can't just use mode "w", which would create an entirely new file.

You are probably using Windows 9x which likes to turture people. Windows 9x (including ME) buffers INI file changes and doesn't commit them immediately. To flush the buffers use WriteINIStr inifile.ini "" "" "" on b2 or FlushINI inifile.ini in the latest CVS version. See this thread for more information.

BTW, why do you manually add entries to wininit.ini? NSIS does that for you when you use Delete /REBOOTOK or Rename /REBOOTOK and the file is in use. On Windows NT it just uses MoveFileEx.

Please attach large scripts next time.


Ah, I wasn't aware of "Rename". I've been playing with NSIS only for a day or two, so I haven't memorized the reference yet. :)

I was cursing "File" all the time for not having a /REBOOT switch. So I'll have to extract the files to temporary names, then call "Rename /REBOOTOK ...", right ? It's a bit more work, but if it does the trick...
At least now I can drop this horrible function.

Thanks !


Yep, that's exactly how you do it :)