UnauthorizedAccessException cannot resolve Directory.GetFiles failure
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.
}
}
Ignore folders/files when Directory.GetFiles() is denied access
You will have to do the recursion manually; don't use AllDirectories - look one folder at a time, then try getting the files from sub-dirs. Untested, but something like below (note uses a delegate rather than building an array):
using System;
using System.IO;
static class Program
{
static void Main()
{
string path = ""; // TODO
ApplyAllFiles(path, ProcessFile);
}
static void ProcessFile(string path) {/* ... */}
static void ApplyAllFiles(string folder, Action<string> fileAction)
{
foreach (string file in Directory.GetFiles(folder))
{
fileAction(file);
}
foreach (string subDir in Directory.GetDirectories(folder))
{
try
{
ApplyAllFiles(subDir, fileAction);
}
catch
{
// swallow, log, whatever
}
}
}
}
Access to file is denied
As per Directory.GetFiles, the error UnauthorizedAccessException is caused by the following:
The caller does not have the required permission.
Also, I wouldnt run GetFiles with search option as AllDirectories but go through one directory at a time. I used this link:
UnauthorizedAccessException cannot resolve Directory.GetFiles failure
Answer 2 (not the accepted one)
GetFiles Access Denied Exception
When an exception occurs and you catch the exception, you still need to return a result for the function. Initialize your variable files to contain an empty array and then return it after the try-catch-block, so it is always returned, even when an error occurs.
public string[] passFiles(string location)
{
// Create an empty array that will be returned in case something goes wrong
string[] files = new string[0];
try
{
files = Directory.GetFiles(location);
}
catch (UnauthorizedAccessException)
{
// Code here will be hit if access is denied.
}
return files;
}
See also this question for a similar question and some useful answers.
Access to the path is denied when using Directory.GetFiles(...)
If you want to continue with the next folder after a fail, then yea; you'll have to do it yourself. I would recommend a Stack<T>
(depth first) or Queue<T>
(bredth first) rather than recursion, and an iterator block (yield return
); then you avoid both stack-overflow and memory usage issues.
Example:
public static IEnumerable<string> GetFiles(string root, string searchPattern)
{
Stack<string> pending = new Stack<string>();
pending.Push(root);
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, searchPattern);
}
catch { }
if(next != null && next.Length != 0)
foreach (var file in next) yield return file;
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
}
How to continue from a UnauthorizedAccessException error in c# when searching for files
You need to use recursion to query one directory at a time. This way you can catch any unauthorized exceptions and continue your search.
static void Main()
{
foreach (DriveInfo info in DriveInfo.GetDrives().Where(c => c.IsReady))
{
foreach (string file in DirSearch(info.RootDirectory.FullName))
{
Console.WriteLine(file);
}
}
Console.ReadKey(true);
}
private static IList<string> DirSearch(string path)
{
List<string> files = new List<string>();
try
{
foreach (string dir in Directory.GetDirectories(path))
{
foreach (string file in Directory.GetFiles(dir))
{
files.Add(file);
}
files.AddRange(DirSearch(dir));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return files;
}
System.UnauthorizedAccessException when getting files
Your app could not have access rights to some folders, for others you can use the following code:
void DiscoverDirs(string where, List<string> files, Func<FileInfo, bool> filter)
{
try
{
var di = new DirectoryInfo(where);
files.AddRange(di.EnumerateFiles().Where(filter).Select(x => x.FullName));
foreach (var dir in Directory.GetDirectories(where))
{
DiscoverDirs(dir, files, filter);
}
}
catch
{
// no access fo this dir, ignore
}
}
Usage:
DateTime From = DateTime.Now.AddHours(-24);
DateTime To = DateTime.Now;
var ScanSize = 5*1024*1024;
var list = new List<string>();
DiscoverDirs(@"C:\", list,
file => file.LastWriteTime >= From & file.LastWriteTime <= To && file.Length >= ScanSize);
foreach (string name in list)
{
FileInfo file = new FileInfo(name);
string fullname = file.FullName;
Console.WriteLine(file.FullName + " ; " + "last changed at " + " ; " + file.LastWriteTime.ToString());
}
Related Topics
How to Read a Specified Line in a Text File
How to Abort a Task Like Aborting a Thread (Thread.Abort Method)
How to Read a File Even When Getting an "In Use by Another Process" Exception
How Using Try Catch for Exception Handling Is Best Practice
Keeping ASP.NET Session Open/Alive
How to Get the Unix Timestamp in C#
Cannot Delete Directory with Directory.Delete(Path, True)
Get Connection String from App.Config
How to Change Network Settings (Ip Address, Dns, Wins, Host Name) with Code in C#
Passing Properties by Reference in C#
Does C# Have Extension Properties
Convert String[] to Int[] in One Line of Code Using Linq
Difference Between Observablecollection and Bindinglist