我在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 \'。
答案 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;
}
}
}