Removing read only attribute on a directory using C#
Asked Answered
L

10

16

I was successfully able to remove read only attribute on a file using the following code snippet:

In main.cs

FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos();

foreach (var childFolderOrFile in sqlParentFileSystemInfo)
{
    RemoveReadOnlyFlag(childFolderOrFile);
}

private static void RemoveReadOnlyFlag(FileSystemInfo fileSystemInfo)
{
    fileSystemInfo.Attributes = FileAttributes.Normal;
    var di = fileSystemInfo as DirectoryInfo;

    if (di != null)
    {
        foreach (var dirInfo in di.GetFileSystemInfos())
            RemoveReadOnlyFlag(dirInfo);
    }
}

Unfortunately, this doesn't work on the folders. After running the code, when I go to the folder, right click and do properties, here's what I see:

alt text

The read only flag is still checked although it removed it from files underneath it. This causes a process to fail deleting this folder. When I manually remove the flag and rerun the process (a bat file), it's able to delete the file (so I know this is not an issue with the bat file)

How do I remove this flag in C#?

Loeffler answered 5/10, 2010 at 19:16 Comment(0)
P
10

You could also do something like the following to recursively clear readonly (and archive, etc.) for all directories and files within a specified parent directory:

private void ClearReadOnly(DirectoryInfo parentDirectory)
{
    if(parentDirectory != null)
    {
        parentDirectory.Attributes = FileAttributes.Normal;
        foreach (FileInfo fi in parentDirectory.GetFiles())
        {
            fi.Attributes = FileAttributes.Normal;
        }
        foreach (DirectoryInfo di in parentDirectory.GetDirectories())
        {
            ClearReadOnly(di);
        }
    }
}

You can therefore call this like so:

public void Main()
{
    DirectoryInfo parentDirectoryInfo = new DirectoryInfo(@"c:\test");
    ClearReadOnly(parentDirectoryInfo);
}
Pilfer answered 5/10, 2010 at 20:9 Comment(0)
F
6

Try DirectoryInfo instead of FileInfo

DirectoryInfo di = new DirectoryInfo(@"c:\temp\content");
di.Attributes = FileAttributes.Normal;

To clean up attrbutes on files-

foreach (string fileName in System.IO.Directory.GetFiles(@"c:\temp\content"))
{
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName);
    fileInfo.Attributes = FileAttributes.Normal;
}
Farrar answered 5/10, 2010 at 19:20 Comment(1)
This doesn't seem to be working on the directory. I still see the attributes with readonly set.Loeffler
S
3

The dialog just works in a fairly bizarre way. It always shows up the way you see it in your screen shot, whatever the state of the ReadOnly attribute. The checkbox is in the 'indetermined' state. You have to click it and either clear or check it to make it perform its action. And in spite of the prompt text (but not the hint next to the checkbox), it only changes the ReadOnly attribute on the files in the directory, not the directory itself.

Use the attrib command line command to see what is really going on. In all likelihood, your code fails because the directory contains files that have their ReadOnly attribute set. You'll have to iterate them.

Shiite answered 5/10, 2010 at 19:35 Comment(0)
P
3

The read-only flag on directories in Windows is actually a misnomer. The folder does not use the read-only flag. The issue is going to be with the customization. The flag is used by Windows to identify that there are customizations on the folder.

This is an old post, with an issue that is sunsetting, but, figured people might still run into it, as it is pretty annoying when you hit it.

Microsoft's Explanation

Perceptive answered 24/10, 2014 at 15:22 Comment(0)
M
2

Just in case any one happens across this later...

ALL of the other answers posted before mine are either wrong or use unnecessary recursion.

First of all the "Read Only" check box in the property dialog of windows always has the tri-state marker for folders. This is because the folder itself is not read only but the files inside can be.

If you want to set/unset read only flag for ALL files. you can do it simply as follows:

void SetReadOnlyFlagForAllFiles(DirectoryInfo directory, bool isReadOnly)
{
    // Iterate over ALL files using "*" wildcard and choosing to search all directories.
    foreach(FileInfo File in directory.GetFiles("*", SearchOption.All.Directories))
    {
        // Set flag.
        File.IsReadOnly = isReadOnly;
    }
}
Malda answered 3/7, 2014 at 12:2 Comment(2)
And what do you do when the directory is read only so you can't add/delete files from the directory? That's what the OP asked.Arbiter
@Arbiter Not what was asked. And you still have a strange idea that a "Directory" has a read only attribute... it doesn't. Did you try any of the code? OPs code actually does work but only because you can cast DirectoryInfo to FileInfo. What it really does is just sets the attribute on all the files, test it yourself. A directory can't be set to FileAttibutes.Normal or .ReadOnly it is always .Directory. As I said explorer ALWAYS displays intermediate state for directories. Also a BAT file can delete "Read Only" directory any way so it is more likely something else locking on his PC.Malda
T
2

IEnumerable / Lambda solution for recursively removing readonly attribute from directories and files:

new DirectoryInfo(@"some\test\path").GetDirectories("*", SearchOption.AllDirectories).ToList().ForEach(
    di => {
        di.Attributes &= ~FileAttributes.ReadOnly;
        di.GetFiles("*", SearchOption.TopDirectoryOnly).ToList().ForEach(fi => fi.IsReadOnly = false);
    }
);
Terhune answered 16/7, 2014 at 11:26 Comment(0)
W
1

Set the Attributes property on the original dirInfo:

dirInfo.Attributes = FileAttributes.Normal;

FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos();

foreach (var childFolderOrFile in sqlParentFileSystemInfo)
{
    RemoveReadOnlyFlag(childFolderOrFile);
}
Weather answered 5/10, 2010 at 19:22 Comment(1)
Does not work. Still see the attributes with the readonly flag in the 'intdetermined' stateLoeffler
A
0

I see that @DotnetDude said in comments that solutions of guys don't work. To my mind it is happens because guys don't mentioned that need to use File.SetAttributes method to apply new attributes.

Autocorrelation answered 1/7, 2013 at 10:47 Comment(0)
K
0

This may or may not be directly related, but the root issue in your case may be caused by the underlying files. For example, I ran into this issue trying to delete a directory:

System.IO.Directory.Delete(someDirectory, true)

This results in "Access to the path 'blah' is denied". To resolve this underlying problem, I removed the read-only attribute on sub-files and was then able to remove the parent directory. In my case, I was using powershell, so you can use the .NET equivalent.

dir -r $PrePackageDirectory |% {if ($_.PSIsContainer -ne $true){$_.IsReadOnly = $false}}
Kalb answered 9/2, 2015 at 18:13 Comment(0)
L
-1
Shell("net share sharefolder=c:\sharefolder/GRANT:Everyone,FULL")


Shell("net share sharefolder= c:\sharefolder/G:Everyone:F /SPEC B")


Shell("Icacls C:\sharefolder/grant Everyone:F /inheritance:e /T")


Shell("attrib -r +s C:\\sharefolder\*.* /s /d", AppWinStyle.Hide)

this code is working for me.. to share a folder to every one with read and write permission

Lactoflavin answered 13/8, 2013 at 2:53 Comment(1)
@Kiquenet, Shell is not a class; it's a VB.NET function. In C#, you can use Process.Start() for similar behavior (namely, starting another process.) Look up the documentation for the Process and ProcessStartInfo classes for more information. For the purpose of just turning off the Read-Only property, as was the original question, though, I'd recommend using Mark Avenius' answer, rather than starting a new process.Blithesome

© 2022 - 2024 — McMap. All rights reserved.