How to skip system volume information?

ken76

Member
Joined
Nov 15, 2018
Messages
14
Programming Experience
5-10
Can someone help me how to skip system volume information with this code?

C#:
string[] originalFiles = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);

            logFile.Add("Begin SyncDrive backup procedure.");
         
                Array.ForEach(originalFiles, (originalFileLocation) =>
            {
                FileInfo originalFile = new FileInfo(originalFileLocation);
                FileInfo destFile = new FileInfo(originalFileLocation.Replace(sourcePath, destPath));

                if (destFile.Exists)
                {
                    if (originalFile.Length != destFile.Length || originalFile.LastWriteTime != destFile.LastWriteTime)
                    {
                        count++;
                    }
                }
                else
                {
                    count++;
                }
            });
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,130
Location
Sydney, Australia
Programming Experience
10+
If you're asking how to skip a specific file, you need to be able to identify that file. What's different about that file than the others? You simply write an if statement that looks for that identifying feature so it can process the file only if it is not present.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,762
Location
Chesapeake, VA
Programming Experience
10+
How did you determine that system volume information is being included? What is the filename for it? What not just ignore that filename assuming that it is included?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,762
Location
Chesapeake, VA
Programming Experience
10+
I think I see what the issue is. It not a matter of the user's code on lines 3-21 trying to process the "System Volume Information" directory at the root of a drive. The problem is that if the user is not running an administrator, or as a user that has rights to particular folders, the call to Directory.GetFiles(..., SearchOption.AllDirectories) will throw an UnauthorizedAccessException when it encounters a folder for which the current user doesn't have permissions for as it recursively searches for files and folders.

Other than running an administrator, I think the only way around this is to do the recursion yourself one directory at a time. Put appropriate exception handling for the directories that you don't have permissions for. I do not recommend running as an administrator.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,762
Location
Chesapeake, VA
Programming Experience
10+
I found another approach. Use Directory.EnumerateFiles(..., SearchOption.AllDirectories). Then manually get the enumerator from the returned object. Then within a some exception handling code, call MoveNext() to try to get the next item. If an UnauthorizedAccessException is thrown, ignore it and move on to the next item.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,130
Location
Sydney, Australia
Programming Experience
10+
I think I see what the issue is. It not a matter of the user's code on lines 3-21 trying to process the "System Volume Information" directory at the root of a drive. The problem is that if the user is not running an administrator, or as a user that has rights to particular folders, the call to Directory.GetFiles(..., SearchOption.AllDirectories) will throw an UnauthorizedAccessException when it encounters a folder for which the current user doesn't have permissions for as it recursively searches for files and folders.

Other than running an administrator, I think the only way around this is to do the recursion yourself one directory at a time. Put appropriate exception handling for the directories that you don't have permissions for. I do not recommend running as an administrator.
It's almost like actually explaining the problem would be helpful. It's worth noting that .NET Core 2.1 and later include a new overload of GetFiles that allows you to specify that inaccessible folders should be ignored.
 

ken76

Member
Joined
Nov 15, 2018
Messages
14
Programming Experience
5-10
I have also tried this, but with no success.
C#:
string[] originalFiles = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories).Where(f => !Path.GetFileName(f) == @sourcePath + "System Volume Information").ToArray();
Is this a bad approach?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,762
Location
Chesapeake, VA
Programming Experience
10+
That won't work because it is already much too late to filter out the directory name because the unauthorized access exception would have already happened while the array is being built. See the approaches suggested in posts #6, #5, and #4 in order of ease of implementation for getting your desired list.

You do know that if you had just stepped through your code with a debugger instead of just running it, you would have figured out that the exception is happening before your filtering attempt.
 

ken76

Member
Joined
Nov 15, 2018
Messages
14
Programming Experience
5-10
I found another approach. Use Directory.EnumerateFiles(..., SearchOption.AllDirectories). Then manually get the enumerator from the returned object. Then within a some exception handling code, call MoveNext() to try to get the next item. If an UnauthorizedAccessException is thrown, ignore it and move on to the next item.
Do you have a small example, how it is done?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,762
Location
Chesapeake, VA
Programming Experience
10+
No. Actually, yes, but the solution is so simple that you would just end up copying and pasting it and not really learn anything. So instead here is some pseudo code:
C#:
var files = Directory.EnumerateFiles(..., SearchOption.AllDirectories)
var enumerator = files.GetEnumerator()
bool success
do
{
    try
    {
        Call enurmerator.MoveNext() to determine successfully getting the filename
        if successful
            Process the filename in enumerator.Current
    }

   catch UnauthorizedAccessException
   {
       Force success to be true because we are ignoring unauthorized accesses
   }
} while successful
 
Top Bottom