How to handle access denied exceptions to folders and/or files?

José Carlos 886 Reputation points
2023-03-21T20:54:13.0833333+00:00

Hi friends.

I'm making a program to delete empty folders from a certain drive. The program is already ready, but when it finds folders or files without access, the program stops. How do I handle these read-only exceptions? That is, skip these files and continue the search?

Tks

Visual Studio
Visual Studio
A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.
4,641 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,306 questions
{count} votes

Accepted answer
  1. Ayomide Oluwaga 946 Reputation points
    2023-03-21T22:45:08.7733333+00:00
    using System.IO;
    
    public static void DeleteEmptyFolders(string path)
    {
        foreach (string directory in Directory.GetDirectories(path))
        {
            try
            {
                if (Directory.GetFiles(directory).Length == 0 && Directory.GetDirectories(directory).Length == 0)
                {
                    Directory.Delete(directory);
                    Console.WriteLine($"{directory} has been deleted.");
                }
                else
                {
                    DeleteEmptyFolders(directory);
                }
            }
            catch (UnauthorizedAccessException e)
            {
                Console.WriteLine($"Error deleting {directory}: {e.Message}");
                continue;
            }
        }
    }
       
    

6 additional answers

Sort by: Most helpful
  1. José Carlos 886 Reputation points
    2023-03-23T23:19:47.3966667+00:00

    Hi Ayomide

    Did not work. He tried to delete an already deleted folder. After some tinkering, I was able to resolve the m based on that code you last sent me.

    See how it turned out:

    public static void DeleteEmptyFolders(string path)
    {
        string[] subDirectories = Directory.GetDirectories(path);
    
        foreach (string subDirectory in subDirectories)
        {
            DeleteEmptyFolders(subDirectory);
    
            if (Directory.GetFiles(subDirectory).Length == 0 && 
                Directory.GetDirectories(subDirectory).Length == 0)
            {
                Directory.Delete(subDirectory);
            }
        }
    }
    
    Thank you very much.
    It helped a lot.
    
    1 person found this answer helpful.

  2. José Carlos 886 Reputation points
    2023-03-21T22:29:50.36+00:00

    I am using C#.

    I tried to do a try catch but it is stopping on error.

    I wanted that when it found the error it would continue to search another folder.

    0 comments No comments

  3. José Carlos 886 Reputation points
    2023-03-21T23:02:03.27+00:00

    Hi Ayomide,

    Thank you very much.

    Worked perfectly.

    It was exactly what I wanted.

    Hug


  4. Karen Payne MVP 35,196 Reputation points
    2023-03-23T19:05:32.09+00:00

    Even though you have a solution here is a more robust solution,

    
    public class DirectoryOperations
    {
        public delegate void OnDelete(string status);
        /// <summary>
        /// Callback for subscribers to see what is being worked on
        /// </summary>
        public static event OnDelete OnDeleteEvent;
    
        public delegate void OnException(Exception exception);
        /// <summary>
        /// Callback for subscribers to know about a problem
        /// </summary>
        public static event OnException OnExceptionEvent;
    
        public delegate void OnUnauthorizedAccessException(string message);
        /// <summary>
        /// Raised when attempting to access a folder the user does not have permissions too
        /// </summary>
        public static event OnUnauthorizedAccessException UnauthorizedAccessEvent;
    
        public delegate void OnTraverseExcludeFolder(string sender);
        /// <summary>
        /// Called each time a folder is being traversed
        /// </summary>
        public static event OnTraverseExcludeFolder OnTraverseIncludeFolderEvent;
    
        public static bool Cancelled = false;
    
        /// <summary>
        /// Recursively remove an entire folder structure and files with events for monitoring and basic
        /// exception handling. USE WITH CARE
        /// </summary>
        /// <param name="directoryInfo"></param>
        /// <param name="cancellationToken"></param>
        public static async Task RecursiveDelete(DirectoryInfo directoryInfo, CancellationToken cancellationToken)
        {
            if (!directoryInfo.Exists)
            {
                OnDeleteEvent?.Invoke("Nothing to process");
                return;
            }
    
            OnDeleteEvent?.Invoke(directoryInfo.Name);
    
            DirectoryInfo folder = null;
    
            try
            {
                await Task.Run(async () =>
                {
                    foreach (DirectoryInfo dirInfo in directoryInfo.EnumerateDirectories())
                    {
    
                        folder = dirInfo;
    
                        if (
                            (folder.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || 
                            (folder.Attributes & FileAttributes.System) == FileAttributes.System || 
                            (folder.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) {
    
                            OnTraverseIncludeFolderEvent?.Invoke($"* {folder.FullName}");
    
                            continue;
    
                        }
    
                        OnTraverseIncludeFolderEvent?.Invoke($"Delete: {folder.FullName}");
    
                        if (!Cancelled)
                        {
                            await Task.Delay(1, cancellationToken);
                            await RecursiveDelete(folder, cancellationToken);
                        }
                        else
                        {
                            return;
                        }
    
                        if (cancellationToken.IsCancellationRequested)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                        }
    
                    }
    
                    /*
                     * assert if folder should be deleted, yes then
                     * directoryInfo.Delete(true);
                     */
                        
                }, cancellationToken);
    
            }
            catch (Exception exception)
            {
                switch (exception)
                {
                    case OperationCanceledException _:
                        Cancelled = true;
                        break;
                    case UnauthorizedAccessException _:
                        UnauthorizedAccessEvent?.Invoke($"Access denied '{exception.Message}'");
                        break;
                    default:
                        OnExceptionEvent?.Invoke(exception);
                        break;
                }
            }
        }
    }
    
    1 person found this answer helpful.