it-swarm-ru.tech

Доступ к пути запрещен при использовании Directory.GetFiles (...)

Я запускаю код ниже и получаю исключение ниже. Я вынужден поместить эту функцию в try catch или есть другой способ получить все каталоги рекурсивно? Я мог бы написать свою собственную рекурсивную функцию для получения файлов и каталогов. Но мне интересно, есть ли лучший способ.

// get all files in folder and sub-folders
var d = Directory.GetFiles(@"C:\", "*", SearchOption.AllDirectories);

// get all sub-directories
var dirs = Directory.GetDirectories(@"C:\", "*", SearchOption.AllDirectories);

«Доступ к пути« C:\Documents and Settings\»запрещен».

12
Amir Rezaei

Если вы хотите перейти к следующей папке после сбоя, то да; вам придется сделать это самостоятельно. Я бы порекомендовал Stack<T> (сначала глубина) или Queue<T> (сначала длина), а не рекурсию, и блок итератора (yield return); тогда вы избегаете проблем переполнения стека и использования памяти.

Пример:

    public static IEnumerable<string> GetFiles(string root, string searchPattern)
    {
        Stack<string> pending = new Stack<string>();
        pending.Push(root);
        while (pending.Count != 0)
        {
            var path = pending.Pop();
            string[] next = null;
            try
            {
                next = Directory.GetFiles(path, searchPattern);                    
            }
            catch { }
            if(next != null && next.Length != 0)
                foreach (var file in next) yield return file;
            try
            {
                next = Directory.GetDirectories(path);
                foreach (var subdir in next) pending.Push(subdir);
            }
            catch { }
        }
    }
33
Marc Gravell

Вы можете настроить программу так, чтобы вы могли работать только как администратор. 

В Visual Studio :

Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings

После того, как вы щелкнете по нему, в папке свойств проекта будет создан файл с именем app.manifest после того, как он будет создан, вы можете снять флажок с опции Enable ClickOnce Security Settings

Откройте этот файл и измените эту строку:

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

чтобы:

 <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

Это приведет к тому, что программе потребуются права администратора, и это гарантирует, что у вас есть доступ к этой папке. 

9
Yochai Timmer

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

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

Второй вариант выглядит более подходящим. Используйте блок try/catch и пропустите все «запрещенные» каталоги.

2
CesarGon

Этот рекурсивный метод возвращает список всех файлов, которые доступны в папке.

    static List<string> getFilesInDir(string dirPath)
    {
        List<string> retVal = new List<string>();
        try
        {
            retVal = IO.Directory.GetFiles(dirPath, "*.*", IO.SearchOption.TopDirectoryOnly).ToList();
            foreach (IO.DirectoryInfo d in new IO.DirectoryInfo(dirPath).GetDirectories("*", IO.SearchOption.TopDirectoryOnly))
            {
                retVal.AddRange(getFilesInDir(d.FullName));
            }
        }
        catch (Exception ex)
        {
            //Console.WriteLine(dirPath);
        }
        return retVal;
    }
0
Rahil Jan Muhammad

Уже указывалось, что вам нужно сделать это самостоятельно, поэтому я подумал, что поделюсь своим решением, которое позволит избежать коллекций по пути. Следует отметить, что при этом будут игнорироваться все ошибки, а не только AccessDenied. Чтобы изменить это, вы можете просто сделать блоки catch более конкретными.

    IEnumerable<string> GetFiles(string folder, string filter, bool recursive)
    {
        string [] found = null;
        try
        {
            found =  Directory.GetFiles(folder, filter);
        }
        catch { }
        if (found!=null)
            foreach (var x in found)
                yield return x;
        if (recursive)
        {
            found = null;
            try
            {
                found = Directory.GetDirectories(folder);
            }
            catch { }
            if (found != null)
                foreach (var x in found)
                    foreach (var y in GetFiles(x, filter, recursive))
                        yield return y;
        }
    }
0
Paul

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

В статье признаются недостатки метода GetDirectories() ...:

К сожалению, у этого [с использованием метода GetDirectories ()] есть проблемы. Ключевым среди них является то, что некоторые из папки, которые вы пытаетесь прочитать, могут быть настроены так, чтобы текущий пользователь не может получить к ним доступ. Вместо того, чтобы игнорировать папки в доступ к которому у вас ограничен, метод выдает UnauthorizedAccessException. Тем не менее, мы можем обойти эту проблему создав собственный рекурсивный код поиска папок.

... а затем подробно описывает решение:

http://www.blackwasp.co.uk/FolderRecursion.aspx

0
sergeidave