Directory.GetFiles method fails on the first encounter with a folder it has no access rights to.
The method throws an UnauthorizedAccessException (which can be caught) but by the time this is done, the method has already failed/terminated.
The code I am using is listed below:
try
{
// looks in stated directory and returns the path of all files found
getFiles = Directory.GetFiles(
@directoryToSearch,
filetype,
SearchOption.AllDirectories);
}
catch (UnauthorizedAccessException)
{
}
As far as I am aware, there is no way to check beforehand whether a certain folder has access rights defined.
In my example, I'm searching on a disk across a network and when I come across a root access only folder, my program fails.
In order to gain control on the level that you want, you should probably probe one directory at a time, instead of a whole tree. The following method populates the given IList<string>
with all files found in the directory tree, except those where the user doesn't have access:
// using System.Linq
private static void AddFiles(string path, IList<string> files)
{
try
{
Directory.GetFiles(path)
.ToList()
.ForEach(s => files.Add(s));
Directory.GetDirectories(path)
.ToList()
.ForEach(s => AddFiles(s, files));
}
catch (UnauthorizedAccessException ex)
{
// ok, so we are not allowed to dig into that directory. Move on.
}
}
I know this thread is old, but in case someone stumbles upon this and needs an answer, i got a recursive solution here:
public static List<string> GetAllAccessibleFiles(string rootPath, List<string> alreadyFound = null)
{
if (alreadyFound == null)
alreadyFound = new List<string>();
DirectoryInfo di = new DirectoryInfo(rootPath);
var dirs = di.EnumerateDirectories();
foreach (DirectoryInfo dir in dirs)
{
if (!((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden))
{
alreadyFound = GetAllAccessibleFiles(dir.FullName, alreadyFound);
}
}
var files = Directory.GetFiles(rootPath);
foreach (string s in files)
{
alreadyFound.Add(s);
}
return alreadyFound;
}
It returns an List<string>
containing the full path to all files that are in accessible directories below the given root-directory.
Call it like this:
var files = GetAllAccessibleFiles(@"C:\myDirectory");
So one result could be like this:
C:\myDirectory\a\a.txt
C:\myDirectory\a\b.mp3
C:\myDirectory\b\a\a\foo.txt
C:\myDirectory\b\b\b\hello.exe
C:\myDirectory\b\c\bar.jpg
C:\myDirectory\and\so\on.bar
C:\myDirectory\a_file_in_root.bmp
Hope it helps someone!
This is an enhancement to Malcolm's answer (http://stackoverflow.com/a/9831340/226181). This scans all logical drives for a file match pattern and ignores the directories that are not accessible.
static List<string> SearchFiles(string pattern)
{
var result = new List<string>();
foreach (string drive in Directory.GetLogicalDrives())
{
Console.WriteLine("searching " + drive);
var files = FindAccessableFiles(drive, pattern, true);
Console.WriteLine(files.Count().ToString() + " files found.");
result.AddRange(files);
}
return result;
}
private static IEnumerable<String> FindAccessableFiles(string path, string file_pattern, bool recurse)
{
Console.WriteLine(path);
var list = new List<string>();
var required_extension = "mp4";
if (File.Exists(path))
{
yield return path;
yield break;
}
if (!Directory.Exists(path))
{
yield break;
}
if (null == file_pattern)
file_pattern = "*." + required_extension;
var top_directory = new DirectoryInfo(path);
// Enumerate the files just in the top directory.
IEnumerator<FileInfo> files;
try
{
files = top_directory.EnumerateFiles(file_pattern).GetEnumerator();
}
catch (Exception ex)
{
files = null;
}
while (true)
{
FileInfo file = null;
try
{
if (files != null && files.MoveNext())
file = files.Current;
else
break;
}
catch (UnauthorizedAccessException)
{
continue;
}
catch (PathTooLongException)
{
continue;
}
yield return file.FullName;
}
if (!recurse)
yield break;
IEnumerator<DirectoryInfo> dirs;
try
{
dirs = top_directory.EnumerateDirectories("*").GetEnumerator();
}
catch (Exception ex)
{
dirs = null;
}
while (true)
{
DirectoryInfo dir = null;
try
{
if (dirs != null && dirs.MoveNext())
dir = dirs.Current;
else
break;
}
catch (UnauthorizedAccessException)
{
continue;
}
catch (PathTooLongException)
{
continue;
}
foreach (var subpath in FindAccessableFiles(dir.FullName, file_pattern, recurse))
yield return subpath;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With