Удаление атрибута только для чтения в каталоге с использованием С#
Я успешно смог удалить атрибут только для чтения в файле, используя следующий фрагмент кода:
В 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)
Как удалить этот флаг в С#?
Ответы
Ответ 1
Вы также можете сделать что-то вроде следующего, чтобы рекурсивно очистить readonly (и архив и т.д.) для всех каталогов и файлов в указанном родительском каталоге:
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);
}
Ответ 2
Попробуйте DirectoryInfo вместо FileInfo
DirectoryInfo di = new DirectoryInfo(@"c:\temp\content");
di.Attributes = FileAttributes.Normal;
Очистить attrbutes на файлах -
foreach (string fileName in System.IO.Directory.GetFiles(@"c:\temp\content"))
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName);
fileInfo.Attributes = FileAttributes.Normal;
}
Ответ 3
Диалог работает довольно странно. Он всегда показывает, как вы видите это в своем снимке экрана, независимо от состояния атрибута ReadOnly. Флажок находится в "неопределенном" состоянии. Вы должны щелкнуть его и либо очистить, либо проверить, чтобы он выполнил свое действие. И, несмотря на подсказку (но не подсказку рядом с флажком), она изменяет атрибут ReadOnly только на файлы в каталоге, а не на сам каталог.
Используйте команду командной строки атрибута, чтобы увидеть, что происходит. По всей вероятности, ваш код не работает, потому что каталог содержит файлы, у которых есть атрибут ReadOnly. Вам придется перебирать их.
Ответ 4
Флаг только для чтения в каталогах в Windows на самом деле является неправильным. В папке не используется флаг только для чтения. Проблема будет связана с настройкой. Флаг используется Windows для определения того, что в папке есть настройки.
Это старая статья с проблемой, которая заходит на закат, но фигурные люди все еще могут столкнуться с ней, так как это очень раздражает, когда вы ее нажимаете.
Пояснение корпорации Майкрософт
Ответ 5
Задайте свойство Attributes
в исходном dirInfo
:
dirInfo.Attributes = FileAttributes.Normal;
FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos();
foreach (var childFolderOrFile in sqlParentFileSystemInfo)
{
RemoveReadOnlyFlag(childFolderOrFile);
}
Ответ 6
На всякий случай, если это произойдет позже...
ВСЕ другие ответы, опубликованные до моего, либо ошибочны, либо используют ненужную рекурсию.
Прежде всего, флажок "Только для чтения" в диалоговом окне свойств окон всегда имеет маркер tri-state для папок. Это связано с тем, что сама папка не читается, но файлы внутри могут быть.
Если вы хотите установить/отключить флаг только для чтения для ВСЕХ файлов. вы можете сделать это просто следующим образом:
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;
}
}
Ответ 7
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);
}
);
Ответ 8
Я вижу, что @DotnetDude сказал в комментариях, что решения парней не работают. На мой взгляд, это происходит потому, что ребята не упомянули, что нужно использовать метод File.SetAttributes для применения новых атрибутов.
Ответ 9
Это может быть или не быть напрямую связано, но проблема с корнем в вашем случае может быть вызвана базовыми файлами. Например, я столкнулся с этой проблемой, пытаясь удалить каталог:
System.IO.Directory.Delete(someDirectory, true)
В результате "Доступ к пути" бла "отрицается". Чтобы устранить эту проблему, я удалил атрибут "только для чтения" в подфайлах и смог удалить родительский каталог. В моем случае я использовал powershell, поэтому вы можете использовать эквивалент .NET.
dir -r $PrePackageDirectory |% {if ($_.PSIsContainer -ne $true){$_.IsReadOnly = $false}}
Ответ 10
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)
этот код работает для меня.. для обмена папкой с каждым с правами на чтение и запись