在LINQ中C#处理System.UnauthorizedAccessException

时间:2012-09-11 15:49:43

标签: c# linq

我在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 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:2)

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

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

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

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方法的想法是“吞下”你不想要的异常而不阻止其他异常发生。这是一个草案实施,但你明白了。

答案 2 :(得分:1)

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

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

抱歉,我正准备参加一个会议,但我已经给了你足够的谷歌了。如果这个问题仍然没有一个可靠的答案,我会稍后再写。

答案 3 :(得分:1)

使用Catch捕获UnauthorizedAccessException。

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

ExceptionExtensions:

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