The best is to use recursive search and not using SearchOption.AllDirectories
, but rather SearchOption.TopDirectoryOnly
If you use SearchOption.AllDirectories
, one access violation will break your entire loop even before any file/directory is processed. But if you use SearchOption.TopDirectoryOnly
, you only skip what is inaccessible.
Thus, to do it, you can create a method which receives a directory path as input. And in that method, if the input directory have child directory(ies) (see Directory.GetDirectories(string path)
method, you call the method again for each child directory (recursive call) before you process all the files in the directory. Else, get the files (see Directory.GetFiles
) in the directory and process them immediately.
Then for the method above, one way is to prevent the code crash when you cannot access certain file/directory is by using try-catch
block for each child directory reading and file reading. This way, if one file/folder cannot be accessed, your code will still be running, finding the processing the next file/directory.
Alternatively, you can use Directory.GetAccessControl()
per child directory check to see if you have an access to a Directory
before hand (this option is rather hard though).
Edit (code added):
Something like this will do:
public static List<string> GetAllAccessibleDirectories(string path, string searchPattern) {
List<string> dirPathList = new List<string>();
try {
List<string> childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList(); //use TopDirectoryOnly
if (childDirPathList == null || childDirPathList.Count <= 0) //this directory has no child
return null;
foreach (string childDirPath in childDirPathList) { //foreach child directory, do recursive search
dirPathList.Add(childDirPath); //add the path
List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern);
if (grandChildDirPath != null && grandChildDirPath.Count > 0) //this child directory has children and nothing has gone wrong
dirPathList.AddRange(grandChildDirPath.ToArray()); //add the grandchildren to the list
}
return dirPathList; //return the whole list found at this level
} catch {
return null; //something has gone wrong, return null
}
}
And to call it, you can do something like this
string rootpath = @"C:\DummyRootFolder";
List<string> dirList = GetAllAccessibleDirectories(rootpath, "*.*"); //you get all accessible directories here
In the dirList
you will get all the directories that you search for, and if there is access violation along the way, it will only affects sub-directories search due to the try-catch
block.
Note that the rootpath
is excluded in the method. But if you want to add it to the list too, you could simply do
dirList.Insert(0, path); //do this after you get dirList
There are also more complicated ways of doing this by using Directory.GetAccessControl
and PermissionSet
Hope it may clarify.