0

Currently I have a program that searches a user set directory and sub-directories for music files and adds them to a collection. However if one of the directories it comes accross is protected then the program falls over. I wanted to know how I can check if the user has access to the directory before trying to search it to avoid this problem. Below is the code I'm using for the search, it currently contains a basic work around for "System Volume Information" but as there is a possibility that there may be other protected directories I wanted to change this to include them.

    public void SearchForMusic()
    {
        //Searches selected directory and its sub directories for music files and adds their path to ObservableCollection<string> MusicFound
        foreach (string ext in extentions)
        {
            foreach (string song in Directory.GetFiles(SearchDirectory, ext))
            {
                musicFound.Add(song);                   
            }

            foreach (string directory in Directory.GetDirectories(SearchDirectory))
            {
                if (directory.Contains("System Volume Information"))
                {

                }
                else
                {
                    foreach (string song in Directory.GetFiles(directory, ext))
                    {
                    musicFound.Add(song);
                    }

                    foreach (string subDirectory in Directory.GetDirectories(directory))
                    {
                        foreach (string subSong in Directory.GetFiles(subDirectory, ext))
                        {
                            musicFound.Add(subSong);
                        }
                    }
                }
            }
        }
    }

Many thanks :)

2 Answers2

2

By far the easiest way to be sure that you have access to a file system object is to attempt to access it. If it fails with an Access Denied error, then you don't have access. Just detect that error condition and proceed with the next item in the search.

In other words, delegate checking access to the system which is, after all, the ultimate arbiter of access rights.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • +1; @Jonathan: Exception handling (`try`/`catch`) should be reserved for exceptional cases, unless the API you are using gives you no other option. Use state checks or `Try` variants when at all possible. I'm not seeing a convenient one here, though (`GetAccessControl`?). So you might be stuck with an exception handler. But make sure you catch `UnauthorizedAccessException` (or whatever specific exception is getting thrown) and not the base `Exception` class. – Merlyn Morgan-Graham Sep 17 '11 at 13:49
  • 1
    @Merlyn Your point about `try/catch` is valid but it should never override correctness of behvaiour. Avoiding `try/catch` and implementing your own rights checking code might leave you happy about not using using exceptions for normal behaviour but that's no consolation when your program behaves poorly. Also, in my answer I referred to detecting errors rather than exceptions. Good file handling APIs should offer TryXXX variants. – David Heffernan Sep 17 '11 at 13:52
  • I fully agree. My point holds up when you have an existing check method, and when you can be confident that it catches the cases you're interested in. If you can't get code in place that gives that confidence, an exception handler plus a comment stating why you're swallowing exceptions is definitely in order. – Merlyn Morgan-Graham Sep 17 '11 at 13:55
  • 1
    @Merlyn I'm not disagreeing with you at all. Sometimes you are left with no choice but to use exceptions for normal flow control. My point is that correct behaviour of the program should override concerns about using exceptions for flow control. – David Heffernan Sep 17 '11 at 13:57
1

You can check this question by replacing the Write with Read permissions. Also, wrap your code in a try catch block and if the exception is thrown, you can assume (or properly check the exception type to be sure) that the directory cannot be traversed.

Community
  • 1
  • 1
planestepper
  • 3,277
  • 26
  • 38
  • +1; Good reference. It is tough, though, because the methods they recommend seem to be marked `Obsolete` (`SecurityManager.IsGranted`). Also see the comments under David's answer about exception handling - tho you're not wrong :) – Merlyn Morgan-Graham Sep 17 '11 at 13:59
  • True - I have a strong Python background and you probably know the 'ask for forgiveness instead of permission' thinking :) So catching errors becomes usually part of the flow - of course, if there are TrySomething methods they're always better in .NET, and testing to then Catch exceptions is not a recommended way/best practice. – planestepper Sep 17 '11 at 14:06