After some time, I needed to analyze the disk space of my C: drive and used the program I have developed in my previous post and I got an “UnauthorizedAccessException”. After some thinking, I realized that was happening because of some paths that I have not access unless I am an admin.

Running as admin is not a good thing to do and, so, I thought of other ways to get the disk space. Soon, I realized that using GetFiles for all directories, although it was the easiest way to get the information, wasn’t the way to do it: at some point, there would be some path with no access and that exception would be thrown.

If I was using Powershell, I could use the -ErrorAction “SilentlyContinue” to continue without an error message, but there is no such thing in the GetFiles method (here is a suggestion for the .NET Framework designers Smile).

So, I had to enumerate all files, directory by directory and process any exception thrown. I came up to a recursive function like this one:

[sourcecode language=”csharp” padlinenumbers=”true”]
private List<FileInfo> GetFilesInDirectory(string directory)
{
    var files = new List<FileInfo>();
    try
    {
        var directories = Directory.GetDirectories(directory);
        try
        {
            var di = new DirectoryInfo(directory);
            files.AddRange(di.GetFiles("*"));
        }
        catch
        {
        }
        foreach (var dir in directories)
        {
            files.AddRange(GetFilesInDirectory(Path.Combine(directory, dir)));
        }
    }
    catch
    {
    }
 
    return files;
}
[/sourcecode]

Initially, I get all directories in the selected path, then I get all files for that directory and process the subdirectories recursively. All exceptions are caught and swallowed, so the processing doesn’t stop if I don’t have access to the folder. As I made this change, I made another one: the previous code was blocking the program while I was enumerating the files, so I used a Task to enumerate the files in the background:

[sourcecode language=”csharp”]
List<FileInfo> files = null;
await Task.Factory.StartNew( () =>
  files = GetFilesInDirectory(selectedPath)
    .Where(f => f.Length >= minSize)
    .OrderByDescending(f => f.Length)
    .ToList());
[/sourcecode]

That way, the enumeration doesn’t block the UI and the program remains responsible all times.

With these changes, everything was working fine and I had a program that could analyze my disk space, even if I had no access to all folder in the disk.

The full source code for the project is in https://github.com/bsonnino/DiskAnalysis

Leave a Reply

Your email address will not be published. Required fields are marked *

Post Navigation