Why does IFileDialog still show non-filesystem folders when I pass FOS_FORCE­FILE­SYSTEM?

Raymond Chen

If you use IFileDialog with the FOS_FORCE­FILE­SYSTEM flag, or SHBrowseForFolder with the BIF_RETURN­ONLY­FS­DIRS flag, the dialog nevertheless shows non-filesystem folders, and if users pick one, they are told “You can’t save here.” Why show users folders that they can’t pick?

Because they may need to pass through these unpickable folders in order to get something that they can pick.

If the folder picker dialogs suppressed unpickable folders, then that would make it impossible to pick any of you local drives because they all live inside the unpickable “This PC” node!

Each IShellFolder can report that an item could potentially lead to a file system location by setting the SFGAO_FILE­SYS­ANCESTOR attribute. If that attribute is reported, then the item will appear in the file picker dialogs. It may not itself be pickable, but it needs to be shown because it potentially leads to pickable items.

13 comments

Discussion is closed. Login to edit/delete existing comments.

  • Paul Topping 0

    This makes sense but will a folder be hidden if it contains only non-filesystem items (recursively)? While the mechanism has a logical explanation, it is still unclear it is useful.

    • Raymond ChenMicrosoft employee 0

      Yes. If a folder is purely virtual, then it will be suppressed. For example you don’t see Control Panel. The ones that are shown are those that declare themselves to be SFGAO_FILESYSANCESTOR. “I am myself a file system folder, or I have a descendant that is a file system folder.”

      • GL 0

        >will a folder be hidden if it contains only non-filesystem items (recursively)?
        >Yes.
        >… I have a descendant that is a file system folder.

        I would be very surprised if that were the case. My understanding is that a folder is hidden if it cannot contain file-system folders, which is a separate concept from whether it currently has a descendant that is a file-system folder. I’m not sure if network shares are part of the file system (SFGAO says parsed names of file-system items are valid Win32 paths, which can use UNC or drive letter; although UNC can point to the local machine, I suspect that its primary usage is for network shares) — if so, then I expect “Network” to be shown even if network discovery is currently off, because it might contain pickable items once network discovery is turn on.

        • Ron Parker 0

          The docs for SFGAO_FILESYSANCESTOR say “The specified folders are either file system folders or contain at least one descendant (child, grandchild, or later) that is a file system (SFGAO_FILESYSTEM) folder.”

          It’s up to the provider to make that determination, of course, and some providers could decide to take the easy way out and say “I could, therefore I do” rather than actually keeping track, but the docs are pretty clear about what it’s supposed to mean.

          • skSdnW 0

            Caching is a possible issue if the folder is dynamic regarding this flag.

            See the documentation for SFGAO_HASSUBFOLDER, if that flag is not set you can be 100% sure there are no subfolders. If the flag is set, maybe it does.

          • GL 0

            I would say it is a documentation bug, because it is illogical and “Network” indeed works as I anticipated. Turn off network discovery, access Network once, then run the following code. When file-system folders are forced, Network is shown (not selectable) even if it currently contains no selectable items, and Control Panel is not shown; when file-system folders are not forced, Network is shown (selectable) and Control Panel is shown.

            /*
            cl /O2 /Ot /Ox /Oy /EHsc /GA /permissive- /utf-8 /validate-charset /MD /W4 sfgao.cc && sfgao
            */
            #pragma comment(lib, "user32")
            #pragma comment(lib, "ole32")
            #pragma comment(lib, "shlwapi")
            #pragma comment(lib, "shell32")
            #define UNICODE
            #define _UNICODE
            #define WIN32_LEAD_AND_MEAN
            #include
            #include
            #include
            #include
            #include
            
            void TestSHBrowseForFolder(WCHAR const *title, UINT flags)
            {
              WCHAR path[MAX_PATH+1] = {};
              BROWSEINFOW browseInfo =
              {
                nullptr,
                nullptr,
                path,
                title,
                flags ,
                nullptr
              };
              auto pidl = SHBrowseForFolderW(&browseInfo);
              if (pidl)
              {
                CoTaskMemFree(pidl);
              }
            }
            
            void TestFileOpenDialog(WCHAR const *title, FILEOPENDIALOGOPTIONS flags)
            {
              IFileDialog *pfd;
              if (!SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog,
                nullptr, CLSCTX_ALL,
                IID_IFileDialog, (void **)&pfd)))
              {
                return;
              }
              if (SUCCEEDED(pfd->SetTitle(title))
                && SUCCEEDED(pfd->SetOptions(flags)))
              {
                HRESULT hr = pfd->Show(nullptr);
                if (SUCCEEDED(hr) || hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
                {
                  /* Operation succeeded. */
                }
              }
              pfd->Release();
            }
            
            int main()
            {
              if (!SUCCEEDED(OleInitialize(nullptr)))
              {
                return -1;
              }
              TestSHBrowseForFolder(L"ReturnOnlyFSDirs | UseNewUI",
                BIF_RETURNONLYFSDIRS | BIF_USENEWUI);
              TestSHBrowseForFolder(L"UseNewUI", BIF_USENEWUI);
              TestFileOpenDialog(L"ForceFileSystem | PickFolders",
                FOS_FORCEFILESYSTEM | FOS_PICKFOLDERS);
              TestFileOpenDialog(L"PickFolders", FOS_PICKFOLDERS);
              OleUninitialize();
              return 0;
            }
          • Raymond ChenMicrosoft employee 0

            It’s just a UI guide. In practice, it’s “contains or could contain”, because it’s possible that a file system child item appears dynamically while the dialog is open, so you need to be there just in case.

  • Mohammad Ghasemi 0

    Thank you. I didn’t even know such an option exists.

  • Mohammad Ghasemi 0

    I enabled FOS_FORCEFILESYSTEM option but I still can select “3D Objects” folder.
    Is this an ordinary folder?

    • skSdnW 1

      It’s special in the same way your pictures folder is special.

      • Mohammad Ghasemi 0

        thank you.

    • Me Gusta 1

      The KNOWNFOLDERID documentation states that FOLDERID_Objects3D has a path. It is likely that it is being shown because it can have a path even though it doesn’t exist by default these days.

      • Mohammad Ghasemi 0

        thank you;

Feedback usabilla icon