简体   繁体   English

在LINQ中C#处理System.UnauthorizedAccessException

[英]C# Handle System.UnauthorizedAccessException in LINQ

I am using below LINQ query to get the directory list. 我在LINQ查询下使用以获取目录列表。 I am getting an error (System.UnauthorizedAccessException was unhandled by user code). 我收到一个错误(System.UnauthorizedAccessException未被用户代码处理)。 How to load only the directories to which I have access to. 如何仅加载我有权访问的目录。

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

Error: 错误:

Access to the path '\\testnetwork\\abc$\\DemoFolder\\' is denied. 访问路径'\\ testnetwork \\ abc $ \\ DemoFolder \\'被拒绝。

I don't see why you need LINQ for this. 我不明白你为什么需要LINQ。 Keeping it simple might help to debug the issue. 保持简单可能有助于调试问题。 Try something like this: 尝试这样的事情:

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

The first thing you should do is change the method you are using: 您应该做的第一件事是更改您正在使用的方法:

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

EnumerateDirectories works better because it yields the results, and still throws the same exception if it finds a folder where it has no rigths. EnumerateDirectories工作得更好,因为它产生结果,并且如果它找到一个没有rigths的文件夹,仍会抛出相同的异常。 The fact that it yields the results allows us to compose on top of its output, so if we add an extension method like this: 它产生结果的事实允许我们在其输出之上进行组合,因此如果我们添加如下的扩展方法:

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

then we are allowed to write something like this: 然后我们被允许写这样的东西:

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

and your output should be the expected one while still keeping the Linq expression clean and composable. 并且您的输出应该是预期的,同时仍然保持Linq表达式清洁和可组合。 The idea of the Catch method is to "swallow" the exception you don't want around without preventing the other ones from happening. Catch方法的想法是“吞下”你不想要的异常,而不会阻止其他异常发生。 It's a draft implementation, but you get the idea. 这是一个草案实施,但你明白了。

I believe there are properties called "CanRead" and "CanWrite" on the File and Directory classes in the System.IO namespace. 我相信在System.IO命名空间的File和Directory类中有一些名为“CanRead”和“CanWrite”的属性。 You could use those to determine whether you have rights. 您可以使用它们来确定您是否拥有权利。

The other way that I know of would be to use Code Access Security and write a method that "Demands" the appropriate privileges.... 我所知道的另一种方法是使用代码访问安全性并编写一个“需要”相应权限的方法....

Sorry, I'm just about to go into a meeting, but I've given you enough to Google with. 对不起,我正准备参加一个会议,但我已经给了你足够的谷歌了。 I'll write more later if this question is still without a solid answer. 如果这个问题仍然没有一个可靠的答案,我会稍后再写。

Catch the UnauthorizedAccessException using Catch. 使用Catch捕获UnauthorizedAccessException。 .

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM