FSO returns non-existing subfolders

2019-07-12 01:51发布

问题:

I'm using this code to get the subfolders of a directory:

Dim fo As Scripting.Folder
Set fo = fso.GetFolder(m_sFolder)

Dim nSubfolder As Scripting.Folder

For Each nSubfolder In fo.SubFolders

    Debug.Print "Folder " & fo.Path & " has subfolder " & nSubfolder 

Next

Now when m_sFolder is "C:\Users\MyUser\Documents", one subfolder is "C:\Users\MyUser\Documents\Eigene Bilder". "Eigene Bilder" is what Windows calls the folder "My Pictures" in German language.

However, the folder "C:\Users\MyUser\Documents" doesn't contain either "My Pictures", "Pictures" or "Eigene Bilder".

The folder "My Pictures" is to be found here: C:\Users\MyUser\Pictures

Can anybody tell me why FSO might want to tell me that this directory "C:\Users\MyUser\Documents\Eigene Bilder" exists?

I'm completely baffled.

回答1:

It's not a Directory it's a Junction (or Reparse) Point which is like a redirection to another location at the filesystem level.

dir "C:\Users\MyUser\Documents\" /ad

From the command line will list these with a <JUNCTION> tag (as opposed to <DIR>).

There is no need to use the FSO, the built in filesystem functions will not include these:

Dim path As String: path = "C:\Users\MyUser\Documents\"
Dim dirn As String

dirn = Dir$(path, vbDirectory)

Do While dirn <> ""
    If (GetAttr(path & dirn) And vbDirectory) = vbDirectory And dirn <> "." And dirn <> ".." Then
        Debug.Print path & dirn
    End If
    dirn = Dir$()
Loop


回答2:

If you insist on using the FSO you need to be aware of these things. This example makes an attempt to be aware, and should give you the information you need to deal with this:

Const ssfPERSONAL = 5
Const FILE_ATTRIBUTE_REPARSE_POINT = &H400&
Dim TargetFolderPath As String
Dim SubFolder As Scripting.Folder
Dim SubFile As Scripting.File

'Don't early-bind to Shell32 objects, Microsoft has failed
'to maintain binary compatibility across Windows versions:
TargetFolderPath = CreateObject("Shell.Application").NameSpace(ssfPERSONAL).Self.Path
Debug.Print TargetFolderPath
With New Scripting.FileSystemObject
    With .GetFolder(TargetFolderPath)
        For Each SubFolder In .SubFolders
            With SubFolder
                Debug.Print .Name;
                Debug.Print " ["; .Type;
                If .Attributes And FILE_ATTRIBUTE_REPARSE_POINT Then
                    Debug.Print ", reparse point";
                End If
                Debug.Print "]"
            End With
        Next
        For Each SubFile In .Files
            With SubFile
                Debug.Print .Name; " ["; .Type; "]"
            End With
        Next
    End With
End With


标签: vb6 fso