C #: Как проверить, могу ли я прочитать и / или удалить каталог - PullRequest
5 голосов
/ 22 октября 2009

Я рекурсивно перебираю кучу каталогов. Некоторые из них (например, D: \ $ RECYCLE.BIN \ S-1-5-20 ) дают мне System.UnauthorizedAccessException. Я полагаю, что я могу просто поймать это и двигаться дальше, но я бы предпочел это выяснить заранее.

Итак, когда у меня есть DirectoryInfo объект. Как я могу узнать, разрешено ли мне GetDirectories() и, возможно, Delete() это?

Ответы [ 4 ]

12 голосов
/ 22 октября 2009

Если вы намереваетесь удалить его, попробуйте удалить его и затем продолжить (обрабатывая исключение соответствующим образом).

Если вы выполните проверку, а затем удалите, если нужно быть в состоянии удалить, существует вероятность возникновения состязания в файловой системе, пусть и незначительного. Это относится к большинству всех операций доступа к файлам / каталогам. Большинство операций с файловой системой спроектированы так, чтобы быть атомарными, и перемещение этой логики в код пользователя противоречит этой атомарности, и все же необходимо обработать возможное исключение, которое возникает.

4 голосов
/ 22 октября 2009

Я построил следующий код. Пожалуйста, посмотрите, поможет ли это:

//using System.IO;
//using System.Security.AccessControl;
//using System.Security.Principal;

string[] directories = Directory.GetDirectories(
    Path.Combine(Environment.CurrentDirectory, @"..\.."), 
    "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
    DirectoryInfo info = new DirectoryInfo(directory);
    DirectorySecurity security = info.GetAccessControl();
    Console.WriteLine(info.FullName);
    foreach (FileSystemAccessRule rule in 
             security.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference = {0}", rule.IdentityReference);
        Console.WriteLine("\tInheritanceFlags  = {0}", rule.InheritanceFlags );
        Console.WriteLine("\tPropagationFlags  = {0}", rule.PropagationFlags );
        Console.WriteLine("\tAccessControlType = {0}", rule.AccessControlType);
        Console.WriteLine("\tFileSystemRights  = {0}", rule.FileSystemRights );
        Console.WriteLine();
    }
}

Результат:

D:\Projects\ConsoleApplication1\bin
    IdentityReference = BUILTIN\Administrators
    InheritanceFlags  = ContainerInherit, ObjectInherit
    PropagationFlags  = None
    AccessControlType = Allow
    FileSystemRights  = FullControl

Обратите внимание, что IdentityReference и FileSystemRights свойства; вероятно, вам следует проверить свой текущий ACL на них, прежде чем пытаться удалить каталог.

0 голосов
/ 10 февраля 2011

Я нашел это, пытаясь решить проблему ...

Кажется, связанный, но довольно не поддерживаемый код, я не пробовал

http://technolog.nl/blogs/eprogrammer/archive/2009/06/18/Howto_3A00_-Properly-use-the-AccessCheck-API.aspx

привет

Mario

0 голосов
/ 22 октября 2009

Полагаю, вам нужно написать собственный метод GetDirectories();который рекурсивно получает те, что находятся внутри него.

В этой статье Microsoft есть хорошая статья о том, как это сделать, и немного поработав, вы можете очистить ее, чтобы использовать общие списки и сделатьэто соответствует вашему решению.

Проще говоря, System.IO.Directory.GetDirectories () будет завершаться ошибкой каждый раз, когда получит одно из этих исключений.

Код примерно такой (скопированный сверху) долженНачало работы

    List<String> directories = new List<String>();
    void DirSearch(string sDir) 
    {
        try 
        {
            foreach (string d in Directory.GetDirectories(sDir)) 
            {
                //foreach (string f in Directory.GetFiles(d, txtFile.Text)) 
                //{
                //    
                //}
                // use this to search for files recursivly.
                directories.Add(d);
                DirSearch(d);
            }
        }
        catch (System.Exception excpt) 
        {
            Console.WriteLine(excpt.Message);
        }
    }

После того, как у вас есть список каталогов, вы можете выполнять над ними операции, и с некоторыми модами вышеописанный метод должен гарантировать, что у вас есть права на чтение для всего списка.

...