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

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

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

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

替代文字

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

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

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

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

尝试使用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; } 

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

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

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

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

微软的解释

在原始dirInfo上设置Attributes属性:

 dirInfo.Attributes = FileAttributes.Normal; FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos(); foreach (var childFolderOrFile in sqlParentFileSystemInfo) { RemoveReadOnlyFlag(childFolderOrFile); } 

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

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

首先,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; } } 

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

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

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

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

这导致“访问路径’blah’被拒绝”。 为了解决这个潜在的问题,我删除了子文件的只读属性,然后删除了父目录。 在我的例子中,我使用的是powershell,因此您可以使用.NET等价物。

 dir -r $PrePackageDirectory |% {if ($_.PSIsContainer -ne $true){$_.IsReadOnly = $false}} 
 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) 

这段代码对我有用..为每个人分享一个具有读写权限的文件夹