1

I have a simple method that counts the size of the directory and all files within it. Here is the code:

using System;
using System.IO;

namespace MyProject.Libs
{
    public sealed class DirectorySize
    {
        public static long GetDirectorySize(DirectoryInfo dir)
        {
            long total = 0;

            FileInfo[] fileInfos = dir.GetFiles();
            foreach (FileInfo fileInfo in fileInfos)
            {
                total += fileInfo.Length;
            }

            DirectoryInfo[] dirInfos = dir.GetDirectories();
            foreach (DirectoryInfo dirInfo in dirInfos)
            {
                total += DirectorySize.GetDirectorySize(dirInfo);
            }

            return total;
        }
    }
}

When I use it on drive c:\ I get "UnauthorizedAccessException" with a message "Access to the path 'C:\Documents and Settings' is denied." That is:

DirectoryInfo di = new DirectoryInfo(Path.GetPathRoot(Environment.SystemDirectory));
long ds = DirectorySize.GetDirectorySize(di);

Tried to run Visual Studio as Administrator. All the same. Why?

Nikolay Dutchuk
  • 683
  • 2
  • 6
  • 11
  • The C:\Documents and Settings folder is disabled for looking into it since Vista. Try using C:\Users instead :) – Marco Klein Dec 28 '12 at 22:04
  • Where are you getting the exception? Tried to wrap the DirectioryInfo in a try catch statement? – eandersson Dec 28 '12 at 22:05
  • I get the exception at `FileInfo[] fileInfos = dir.GetFiles();` line. Also, I use `Environment.SystemDirectory` as starting point thus I have no control over what directories are found. I tried to use try/catch block, but then I get the wrong total size. – Nikolay Dutchuk Dec 28 '12 at 22:10

3 Answers3

3

There are files and folders you don't have permissions to access, even as administrator. The best you can do is add some exception handling and hope the information you return is reasonably complete.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
3

Your code fails on C:\Documents and Settings which is now a junction point that points to C:\Users. You could check that with the FileAttributes.ReparsePoint of the directory.

Here's the modified code with additional exception handling(for other dirs which you are not authorized):

public sealed class DirectorySize
{
    public static long GetDirectorySize(DirectoryInfo dir)
    {
        long total = 0;
        FileAttributes attributes = File.GetAttributes(dir.FullName);
        if (!((attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint))
        {
            try{
                FileInfo[] fileInfos = dir.GetFiles();
                foreach (FileInfo fileInfo in fileInfos)
                {
                    total += fileInfo.Length;
                }

                DirectoryInfo[] dirInfos = dir.GetDirectories();
                foreach (DirectoryInfo dirInfo in dirInfos)
                {
                    total += DirectorySize.GetDirectorySize(dirInfo);
                }
            } catch (UnauthorizedAccessException)
            { 
                // log this?
            }
        }

        return total;
    }
}

Junction Points (Windows)

In Windows Vista and Windows Server 2008, the default locations for user data and system data have changed. For example, user data that was previously stored in the %SystemDrive%\Documents and Settings directory is now stored in the %SystemDrive%\Users directory. For backward compatibility, the old locations have junction points that point to the new locations. For example, C:\Documents and Settings is now a junction point that points to C:\Users. Backup applications must be capable of backing up and restoring junction points. These junction points can be identified as follows: They have the FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_HIDDEN, and FILE_ATTRIBUTE_SYSTEM file attributes set. They also have their access control lists (ACLs) set to deny read access to everyone. Applications that call out a specific path can traverse these junction points if they have the required permissions. However, attempts to enumerate the contents of the junction points will result in failures.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

There are some folders where even the administrator has no permission to visit them. This most of the time happens with translated systems. For example the "program files" folder would be called "programme" in german. You have no access to "programme" within the code but to "program files"

Marco Klein
  • 683
  • 5
  • 19
  • That is good information to prevent people from hardcoding paths into their application, but in this case, the OP is enumerating all of the directories in the C drive and wondering why some are throwing exceptions. Because of this, it couldn't be a translation error, so there is another root cause (identified by evanmcdonnal). – competent_tech Dec 28 '12 at 22:11