Archive: Not deleting a writeable file


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


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

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


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


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


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.


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

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?


Yes that should work :D

-Stu


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"

Instructor - thanks for that.
Calum