Set file attributes recurisvely
Is there a easy way to set just change the write protection attributes of a folder and its files and subfolders? I'm asking because SetFileAttributes works just for one file/folder - or am I wrong?
Thanks :)
CJ
Archive: Set file attributes recurisvely
Set file attributes recurisvely
Is there a easy way to set just change the write protection attributes of a folder and its files and subfolders? I'm asking because SetFileAttributes works just for one file/folder - or am I wrong?
Thanks :)
CJ
Quickest option I can think of is use FindFirst/Next
http://nsis.sourceforge.net/Docs/Chapter4.html#4.9.5.8
I think getting the file attributes, check for READONLY and eventually extract the string in a loop is a kind of complicated way, isn't it?
Do you think, it would be a appropriate way to use:
ExecShell "attrib" "-R /D /S C:\mydir\*"
?I'm sure this can be done a lot more reliable using the system plugin and win32 api.
I don't know, if I don't see something, but for me it looks like using the System plugin an the WinApi results in the same like using SetFileAttributes. Am I wrong?
Added:
I'm having a look at http://msdn.microsoft.com/en-us/library/aa365522(VS.85).aspx and it seems, that your first hint about using FindFirstFile and FindNextFile is the only way I can do it.
I've got a new problem ... *hurrah!* -.-'
I'm to stupid to set the attributes for the files using a variable.
${GetFileAttributes} "C:\mydir\file.txt" "ALL" $R5
StrCpy $R5 "READONLY|$R5"
SetFileAttributes "C:\mydir\file.txt" $R5
Is it not allowed pass the values using a variable?
StrCpy $R5 "READONLY|$R5" () ()
Usage: SetFileAttributes file attribute[|attribute[...]]
attribute=(NORMAL|ARCHIVE|HIDDEN|OFFLINE|READONLY|SYSTEM|TEMPORARY|0)
Error in script "D:\[..]\Installer.nsi" on line 475 -- aborting creation process
I've written a algorithm to solve my problem.
1. The write protection can be removed recursively from directory.
2. The attributes mask of the current file will not be destroyed - what could happen if just set the mask to 'NORMAL'.
-> The functionality shall be used using the macro.
!macro removeWriteProtection _file
Push $0
StrCpy $0 "${_file}"
Call removeWriteProtection
Pop $0
!macroend
Function removeWriteProtection
Push $R0
Push $R1
System::Call "kernel32::GetFileAttributes(t '$0') i.R0"
IntOp $R1 $R0 % 2
${If} $R1 == 1 # odd number -> readonly attribute's set
IntOp $R0 $R0 - 1
System::Call "kernel32::SetFileAttributes(t '$0', i R0)"
${EndIf}
${GetFileAttributes} "$0" "DIRECTORY" $R1
${If} $R1 == 1
loop:
StrCmp $R1 "" done
StrCmp $R1 "." next
StrCmp $R1 ".." next
StrCpy $R1 "$0\$R1"
!insertmacro removeWriteProtection "$R1"
next:
FindNext $R0 $R1
Goto loop
done:
ClearErrors
FindClose $R0
${EndIf}
Pop $R1
Pop $R0
FunctionEnd
System::Call "kernel32::SetFileAttributes(t '$0', i R0)"
But at the moment, I can't imagine how to do so by just returning from a call deep inside the recursion.Couldn't you just do ${If} ${Errors} goto YourBreakLabel?