How to set the system attribute of each folder that contains a desktop.ini?

1.2k views Asked by At

I use a software to backup my HDD to an other HDD. The sofware finds the differences first and mirrors them to the backup HDD then. Unfortunatelly, it ignores the folders' system attributes. This is a problem, because a lot of the folders have modified icons, that are displayed only if the folders' system attributes are set.

To correct this, I want to find all the affected folders. These are the ones that contain a desktop.ini file, so the system attributes should be set of such folders.

I know how to set the system attribute of a folder, but I don't know how to do it recursively, conditionally:

D:\>attrib +s ExampleDirectory

I guess I'll need a Windows batch script, but I'm not sure, as I don't know anything about batch programming.

1

There are 1 answers

3
aschipfl On

If you really want to stick to your backup tool, which apparently cannot handle attributes correctly, you could use the following code based on for/D /R to reapply the System attribute for all directories that contain a file Desktop.ini:

for /D /R "D:\path\to\root\dir" %%D in ("*") do (
    if exist "%%~D\Desktop.ini" (
        if not exist "%%~D\Desktop.ini\" (
            attrib +S "%%~D"
        )
    )
)

The two nested if statements are required to apply the System attribute for directories that contain a file called Desktop.ini, but not for those that contain a directory of that name (although this might occur quite unlikely); the first if condition matches both files and directories, the second one does not match directories (note the trailing \).

Anyway, perhaps you should switch to another backup tool that can handle all attributes correctly, like robocopy, for example, which has been recommended by a comment.


The above approach does not handle hidden items correctly, because for /D does not recognise hidden directories, and attrib does not change the System attribute of hidden files. To overcome this, the code needs to be modified like this:

for /F "delims=" %%D in ('dir /B /S /A:D "D:\path\to\root\dir\*"') do (
    if exist "%%~D\Desktop.ini" (
        if not exist "%%~D\Desktop.ini\" (
            set "HIDDEN=%%~aD"
            setlocal EnableDelayedExpansion
            if not "!HIDDEN!"=="!HIDDEN:h=!" (
                endlocal
                attrib -H "%%~D"
                attrib +H +S "%%~D"
            ) else (
                endlocal
                attrib +S "%%~D"
            )
        )
    )
)

This makes use of the ~a modifier of the for variable reference and sub-string replacement.