Skip to content
⌘ NSIS Forum Archive

Not deleting a writeable file

11 posts

calumm#

Not deleting a writeable file

My installation installs some sample files, which are installed readonly, in order to discourage the user from editing them directly, but instead copy them to another location in order to edit them.

If the user does edit them, I want to not delete them when uninstalling.

So, on uninstallation, I really want to delete them if they're readonly, but leave them if they're writeable.

Is there any way to achieve this?

Thanks,
Calum
Afrow UK#
If they're plain files, you can check if they're readonly with FileOpen...

!macro IsReadOnly File IfIs IfIsnt
Push $R0
Push $R1
ClearErrors
FileOpen $R0 "${File}" r
FileRead $R0 $R1
FileClose $R0
Pop $R1
Pop $R0
IfErrors ${IfIs} ${IfIsnt}
!macroend
!define IsReadOnly "!insertmacro IsReadOnly"
Then do for each file to delete...
${IsReadOnly} "$INSTDIR\File.txt" 0 +2
Delete "$INSTDIR\File.txt"

Edit: You will need to use SetFileAttributes to turn off the readonly flag before deleting the file. Change +2 to +3 then as well.

${IsReadOnly} "$INSTDIR\File.txt" 0 +3
SetFileAttributes "$INSTDIR\File.txt" NORMAL
Delete "$INSTDIR\File.txt"

-Stu
calumm#
Thanks for that - I'll try it out.

Just for my understanding: what is it in opening, reading and closing the file which would generate an error if the file is readonly? (as that's what I understand is happening)

And, I take it there's no built-in way to get file attributes - you've got to take the above round-about way?

Thanks for your help,
Calum
Afrow UK#
Yes, that's how we've always done it.

This would be nice though...
FileAttributeSet "path\to\file" ATTRIBUTE GotoIfSet NotSet

Or perhaps a GetFileAttributes.

Yes, the error flag is set if a file cannot be opened with FileOpen. You could remove the FileRead and the Push $R1 + Pop $R1 and the error flag should still be set but I put them in just in case.

The Push's and Pop's just save the values of $R0 and $R1 if you happen to be using them before and after including the macro.

-Stu
calumm#
Hi again

I guess if it works (haven't been able to try it yet), then it's a bit academic.
But I'm still confused - does FileOpen fail to open a read-only file?

Thanks,
Calum
kichik#
FileOpen should fail on a read-only file, if you try opening it for writing. That's what the read-only attribute is all about.
Afrow UK#edited
Oh yes, sorry for some reason I thought it wouldn't be able to read it 😁
Changed:


!macro IsReadOnly File IfIs IfIsnt
Push $R0
ClearErrors
FileOpen $R0 "${File}" a
FileClose $R0
Pop $R0
IfErrors ${IfIs} ${IfIsnt}
!macroend
!define IsReadOnly "!insertmacro IsReadOnly"
-Stu
calumm#
Ah - I was wondering if the openmode from your original example should be something other than "r".

In the documentation, it says:

"w" (write, all contents of file are destroyed)
"a" (append, meaning opened for both read and write, contents preserved).

So would "a" be more appropriate in my case than "w", as I want to leave the file alone if it's writeable?
Instructor#
FileOpen $R0 "File" a
this is change modification date of file.


calumm you can try this one: GetFileAttributes

${GetFileAttributes} "file" "READONLY" $R0
StrCmp $R0 0 0 +2
MessageBox MB_OK "File isn't READONLY"