2
    Dim dirs As List(Of String)
    dirs = New List(Of String)(IO.Directory.EnumerateDirectories(path, "*", SearchOption.AllDirectories))

The following code works fine for the most part but always fails on the c:\users\documents folder because of Junction points.

I get the following exception and stack trace.

Is there a way to exclude junction points and use EnumerateDirectories or will have to write code to manually get the directory names and ignore/handle junction points?

Exception:
{"Access to the path 'C:\Users\jkfredri\Documents\My Music' is denied."}

Stack Trace:
" at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)" & vbCrLf & " at System.IO.FileSystemEnumerableIterator1.AddSearchableDirsToStack(SearchData localSearchData)" & vbCrLf & " at System.IO.FileSystemEnumerableIterator1.MoveNext()" & vbCrLf & " at System.Collections.Generic.List1..ctor(IEnumerable1 collection)" & vbCrLf & " at BUDWindows.BUD.FileSystem.Directory.GetDirectoriesList(String path) in C:\Users\\Visual Studio\Projects\Desktop Applications\BUDWindows\Classes\FileSystemManager.vb:line 292"

JoshF
  • 159
  • 4
  • 15
  • Possible duplicate of [Directory.EnumerateFiles => UnauthorizedAccessException](http://stackoverflow.com/questions/5098011/directory-enumeratefiles-unauthorizedaccessexception) – Wagner DosAnjos Jan 04 '17 at 22:04
  • As per meta, [Possible duplicate question in another (programming) language](http://meta.stackoverflow.com/q/319542/1070452) a different language makes it not a dupe. Its pretty easy to convert but not for everyone. The link may help a poster, but they *are* different languages and tags. – Ňɏssa Pøngjǣrdenlarp Jan 04 '17 at 23:01

1 Answers1

1

There is a FileAttribute which indicates if it is a ReparsePoint entry. To get at it, you need a DirectoryInfo object. Since each one needs to be tested, you could use DirectoryInfo.EnumerateDirectories() to get a list of them rather than creating them one by one from the names you are getting.

Then, if you just want the name, Select that after the ReparsePoints have been excluded. Extension methods can do most of the work:

Dim dInfo = New DirectoryInfo(dPath)
Dim DirNames = dInfo.EnumerateDirectories("*.*", SearchOption.TopDirectoryOnly).
                Where(Function(q) IsReparse(q) = False).
                Select(Function(q) q.FullName).
                ToList()

For Each s As String In DirNames.ToArray()
    DirNames.AddRange(Directory.
                        EnumerateDirectories(s, "*.*", SearchOption.AllDirectories))
Next

Then, a helper method:

Private Function IsReparse(d As DirectoryInfo) As Boolean
    Return ((d.Attributes And FileAttributes.ReparsePoint) = FileAttributes.ReparsePoint)
End Function

This gets the top level folder names where the Reparse attribute is false, then iterates those to get sub folder names. The premise is that the Reparse folders will be at the top level only. Then with that out of the way, it just adds the sub folders to the list.

Apparently, even testing for the ReparsePoint first doesnt prevent it from looking for sub folders in them with SearchOption.AllDirectories.

You could put the FileAttributes test in the WHERE method, but depending on what you are doing, you may find you also want to skip ones with the System attribute.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178