使用C#删除目录上的只读属性

时间:2010-10-05 19:16:22

标签: c# .net .net-3.5 c#-4.0

我已成功使用以下代码段删除文件的只读属性:

在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);
    }
}

不幸的是,这对文件夹不起作用。运行代码后,当我转到该文件夹​​时,右键单击并执行属性,这是我所看到的:

alt text

虽然将只读标志从其下方的文件中删除,但仍然会检查该标志。这会导致进程无法删除此文件夹。当我手动删除标志并重新运行进程(bat文件)时,它可以删除该文件(所以我知道这不是bat文件的问题)

如何在C#中删除此标志?

10 个答案:

答案 0 :(得分:8)

您还可以执行以下操作,以递归方式清除指定父目录中所有目录和文件的只读(和存档等):

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);
        }
    }
}

你可以这样称呼它:

public void Main()
{
    DirectoryInfo parentDirectoryInfo = new DirectoryInfo(@"c:\test");
    ClearReadOnly(parentDirectoryInfo);
}

答案 1 :(得分:6)

尝试使用DirectoryInfo而不是FileInfo

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

清理文件上的属性 -

foreach (string fileName in System.IO.Directory.GetFiles(@"c:\temp\content"))
{
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName);
    fileInfo.Attributes = FileAttributes.Normal;
}

答案 2 :(得分:3)

对话框的工作方式非常奇怪。它始终显示您在屏幕截图中看到它的方式,无论ReadOnly属性的状态如何。该复选框处于“未确定”状态。您必须单击它并清除或检查它以使其执行其操作。尽管提示文本(但不是复选框旁边的提示),它只会更改目录中文件的ReadOnly属性,而不是目录本身。

使用attrib命令行命令查看实际情况。很可能,您的代码失败,因为该目录包含设置了ReadOnly属性的文件。你必须迭代它们。

答案 3 :(得分:2)

Windows中目录的只读标志实际上是用词不当。该文件夹不使用只读标志。问题将出在定制上。 Windows使用该标志来标识文件夹上有自定义项。

这是一个老帖子,有一个日落问题,但是,想到人们可能仍会遇到它,因为当你点击它时会非常烦人。

Microsoft's Explanation

答案 4 :(得分:1)

在原始Attributes上设置dirInfo属性:

dirInfo.Attributes = FileAttributes.Normal;

FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos();

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

答案 5 :(得分:1)

以防万一发生这种情况......

我之前发布的所有其他答案都是错误的或使用不必要的递归。

首先,"只读" Windows属性对话框中的复选框始终具有文件夹的三态标记。这是因为文件夹本身不是只读的,但里面的文件可以是。

如果要为所有文件设置/取消设置只读标志。你可以这样做:

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;
    }
}

答案 6 :(得分:1)

IEnumerable / Lambda解决方案,用于递归删除目录和文件中的readonly属性:

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);
    }
);

答案 7 :(得分:0)

我看到@DotnetDude在评论中说,家伙的解决方案不起作用。在我看来,这是因为人们没有提到需要使用File.SetAttributes方法来应用新属性。

答案 8 :(得分:0)

这可能与也可能不直接相关,但您的案例中的根本问题可能是由基础文件引起的。例如,我在尝试删除目录时遇到了这个问题:

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

这导致“拒绝访问路径'blah'”。为了解决这个潜在的问题,我删除了子文件的只读属性,然后删除了父目录。就我而言,我使用的是PowerShell,因此您可以使用.NET等效。

dir -r $PrePackageDirectory |% {if ($_.PSIsContainer -ne $true){$_.IsReadOnly = $false}}

答案 9 :(得分:-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)

此代码对我有用..与具有读写权限的每个人共享一个文件夹