3

我正在使用下面的 LINQ 查询来获取目录列表。我收到一个错误(System.UnauthorizedAccessException 未被用户代码处理)。如何仅加载我有权访问的目录。

var files = from f in System.IO.Directory.GetDirectories(@"\\testnetwork\abc$",
                                   "*.*",
                                   SearchOption.AllDirectories)
            select System.IO.Path.GetDirectoryName(f);

错误:

拒绝访问路径 '\testnetwork\abc$\DemoFolder\'。

4

4 回答 4

2

您应该做的第一件事是更改您正在使用的方法:

var files = from f in System.IO.Directory.EnumerateDirectories(
        @"\\testnetwork\abc$",
        "*.*",
        SearchOption.AllDirectories)
select f;

EnumerateDirectories效果更好,因为它会产生结果,并且如果它找到一个没有权限的文件夹,仍然会抛出相同的异常。它产生结果的事实允许我们在它的输出之上进行组合,所以如果我们添加一个这样的扩展方法:

static class ExceptionExtensions
{
    public static IEnumerable<TIn> Catch<TIn>(
                this IEnumerable<TIn> source,
                Type exceptionType)
    {   
        using (var e = source.GetEnumerator())
        while (true)
        {
            var ok = false;

            try
            {
                ok = e.MoveNext();
            }
            catch(Exception ex)
            {
                if (ex.GetType() != exceptionType)
                    throw;
                continue;
            }

            if (!ok)
                yield break;

            yield return e.Current;
        }
    }
}

那么我们就可以这样写:

var files = from f in System.IO.Directory.EnumerateDirectories(
        @"\\testnetwork\abc$",
        "*.*",
        SearchOption.AllDirectories)
        .Catch(typeof(UnauthorizedAccessException))
select f;

并且您的输出应该是预期的,同时仍保持 Linq 表达式的干净和可组合。该Catch方法的想法是在不阻止其他异常发生的情况下“吞下”您不想要的异常。这是一个实施草案,但你明白了。

于 2012-09-11T18:20:39.177 回答
2

我不明白你为什么需要 LINQ。保持简单可能有助于调试问题。尝试这样的事情:

DirectoryInfo[] directories = System.IO.Directory.GetDirectories(@"\\testnetwork\abc$",
                               "*.*",
                               SearchOption.AllDirectories);
foreach (DirectoryInfo dir in directories)
{
    try
    {
       Console.WriteLine(System.IO.Path.GetDirectoryName(f));
    }
    catch(Exception ex)
    {
       // report an error or something
    }
}
于 2012-09-11T15:56:20.813 回答
1

我相信 System.IO 命名空间中的 File 和 Directory 类中有名为“CanRead”和“CanWrite”的属性。您可以使用这些来确定您是否拥有权利。

我知道的另一种方法是使用代码访问安全性并编写一个“要求”适当权限的方法......

抱歉,我正要参加一个会议,但我已经为你提供了足够的内容供 Google 使用。如果这个问题仍然没有可靠的答案,我稍后会写更多。

于 2012-09-11T15:55:12.927 回答
1

使用 Catch 捕获 UnauthorizedAccessException。.

  string[] directories = Directory.EnumerateDirectories(@"\\testnetwork\abc$","*.*", SearchOption.AllDirectories).Catch(typeof(UnauthorizedAccessException)).ToArray();

异常扩展:

   static class ExceptionExtensions
{
public static IEnumerable<TIn> Catch<TIn>(
            this IEnumerable<TIn> source,
            Type exceptionType)
{   
    using (var e = source.GetEnumerator())
    while (true)
    {
        var ok = false;

        try
        {
            ok = e.MoveNext();
        }
        catch(Exception ex)
        {
            if (ex.GetType() != exceptionType)
                throw;
            continue;
        }

        if (!ok)
            yield break;

        yield return e.Current;
    }
}
}
于 2012-09-11T16:00:50.980 回答