0

I want to continue my code when error comes up , but i dont know how ...

here's my code :

foreach(string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories)
{
    Console.WriteLine(path);
}

And the error comes on foreach(string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories) and i don't know how to continue this loop

and the error :

Unauthorized access

And even i run my code as Administrator this error comes up again

Thanks,

H H
  • 263,252
  • 30
  • 330
  • 514
Al00X
  • 1,492
  • 1
  • 12
  • 17

3 Answers3

1

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.

Community
  • 1
  • 1
Ian
  • 30,182
  • 19
  • 69
  • 107
  • I can't get what is your mean... if its possible , write the code Thanks – Al00X Dec 28 '15 at 17:06
  • Code added according to your request, see if it clarifies what I mean – Ian Dec 29 '15 at 02:48
  • Glad that you find it helpful! =) But please note that this code is simple yet not optimal. This is because you only realize that you violate certain directory access control **after** you try to read it. This will impair your performance at some level. So, just in case you need better solution, you might need to use `GetAccessControl` method. – Ian Dec 29 '15 at 04:27
0

According to the documentation, you should look at EnumerateDirectories for performance reasons:

https://msdn.microsoft.com/en-us/library/c1sez4sc(v=vs.110).aspx

Also, it appears that this question has already been answered before:

Directory.EnumerateFiles => UnauthorizedAccessException

Hope this helps!

Community
  • 1
  • 1
ohiodoug
  • 1,493
  • 1
  • 9
  • 12
0

How about this:

foreach (string path in Directory.GetDirectories(@"C:\", "*.*", SearchOption.AllDirectories)) {

            try { 
                Console.WriteLine(path);
            } catch (Exception ex) {
                Console.WriteLine("Unable to access directories in path: " + path);
            }
        }
RonC
  • 31,330
  • 19
  • 94
  • 139
  • You don't want to catch on any kind of exception. You probably want to be as explicit as possible with catching exceptions (in this case). – But I'm Not A Wrapper Class Dec 28 '15 at 16:46
  • @CyberneticTwerkGuruOrc I disagree in this case given that the original poster said "I want to continue my code when error comes up , but i dont know how" He didn't say he wanted to continue for some errors but not others, he said for all errors which is exactly what my code does. – RonC Dec 29 '15 at 14:22