- NSIS Discussion
- Not deleting a writeable file
Archive: Not deleting a writeable file
calumm
6th May 2005 17:22 UTC
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
6th May 2005 18:03 UTC
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
6th May 2005 20:12 UTC
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
6th May 2005 21:46 UTC
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
7th May 2005 00:28 UTC
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
7th May 2005 04:27 UTC
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
7th May 2005 12:21 UTC
Oh yes, sorry for some reason I thought it wouldn't be able to read it :D
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
7th May 2005 12:31 UTC
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?
Afrow UK
7th May 2005 13:13 UTC
Yes that should work :D
-Stu
Instructor
7th May 2005 20:45 UTC
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"
calumm
10th May 2005 09:03 UTC
Instructor - thanks for that.
Calum