Why does SHGetSpecialFolderPath take such a long time before returning a network error?


A customer reported that their program was failing to start up because the call to SHGet­Special­Folder­Path(CSIDL_PERSONAL) was taking a long time and then eventually returning with ERROR_BAD_NETPATH. The account that was experiencing this problem had a redirected network profile, “but even if he’s redirecting, why would we get the bad net path error? Does calling SHGet­Folder­Path actually touch the folder/network? If so, we should probably stop calling this function on the UI thread since network problems could cause our program to hang.”

The SHGet­Folder­Path function will access the network if you pass the CSIDL_FLAG_CREATE flag, which says “Check if the folder is there, and if not, create it.”

The customer had been passing the flag. “We’ll remove it. As if our program is going to dictate the creation of the user profile directory.”

The CSIDL_FLAG_CREATE flag has been implicated in some other unwanted behavior. For example, if you pass the CSIDL_FLAG_CREATE flag when asking for CSIDL_MYPICTURES, this will create a My Pictures directory if there wasn’t one before. Generally speaking, you shouldn’t be creating these directories as side-effects of other actions. Corporate administrators may suppress creation of folders like Pictures and Videos, but that doesn’t do much good if your program casually creates them as part of its startup.

Note that SHGet­Special­Folder­Path and CSIDL values have been superseded by SHGet­Known­Folder­Path and KNOWN­FOLDER­ID. The flag corresponding to CSIDL_FLAG_CREATE is KF_FLAG_CREATE. If you want to make things even faster, consider passing the KF_FLAG_DONT_VERIFY flag (formerly known as CSIDL_FLAG_DONT_VERIFY).

Comments (6)
  1. Dan Bugglin says:

    So, why WAS it returning ERROR_BAD_NETPATH?  Shouldn't it have still worked, even if it did access the network?

  2. Maurits says:

    Perhaps the computer was a laptop and wasn't connected to the corporate network at the time.

  3. configurator says:

    So if you get a special folder to save your pictures in and it doesn't exist – where are you supposed to save the picture instead?

    [Assume a picture-saving program that can't access UI conveniently; e.g. a game where you press printscreen but you can't pause the game to show a save as dialog].

  4. James Schend says:

    Dan: Reading between the lines, it looks like the user had redirected their profile folder to a network share that was offline. The function attempted to connect the share so that it could verify the folder existed (since they told it to do that), and timed-out.

    If you told the function "return the path *and* ensure the path exists", it has to actually check that the path exists before returning– otherwise the function would only be doing half of what you told it to do.

  5. Cheong says:

    @configurator: Perheps creates a folder in My Documents that matches your application name… I've seen lots of online games that support screen captures do this.

    Btw, nothing stops your from allowing users to set the path in "Options" screen…

  6. nikos says:

    there is an issue with network paths in general. Windows explorer seems to be obtaining contents from network drives very quickly but if you try regular shell API (IShellFolder etc) in a program to enumerate remote items, then chances are it will take ages, at least the first time round (from then on it seems that there is some caching)

    If there is any documentation about how to speedup network access in general, I wasn't able to find it. If you have any ideas please tell us where to find this kind of information

    thanks

Comments are closed.