Check if DirectoryInfo.FullName is special folder
Asked Answered
S

5

3

My goal is to check, if DirectoryInfo.FullName is one of the special folders.

Here is what I'm doing for this (Check directoryInfo.FullName to each special folder if they are equal):

        DirectoryInfo directoryInfo = new DirectoryInfo("Directory path");

        if (directoryInfo.FullName == Environment.GetFolderPath(Environment.SpecialFolder.Windows) ||
            directoryInfo.FullName == Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles ||) 
            ...
            ...
           )
        {
            // directoryInfo is the special folder
        }

But there are many special folders (Cookies, ApplicationData, InternetCache, etc.). Is there any way to do this task more efficiently?

Thanks.

Switch answered 20/8, 2011 at 11:3 Comment(0)
A
6

Try this following code :

        bool result = false;
        DirectoryInfo directoryInfo = new DirectoryInfo("Directory path");
        foreach (Environment.SpecialFolder suit in Enum.GetValues(typeof(Environment.SpecialFolder)))
        {
            if (directoryInfo.FullName == Environment.GetFolderPath(suit))
            {
                result = true;
                break;
            }
        }

        if (result)
        {
            // Do what ever you want
        }

hope this help.

Arrogance answered 20/8, 2011 at 11:19 Comment(1)
Any idea how this handles translation, writing systems and case-sensitivity? I genuinely can't tell from looking in the docs. If do try out, I'll let SO know.Astatine
B
1

I'm afraid the answers given seem to be the only way, I hate the special folders because what ought to be a very simple function -

void CollectFiles(string strDir, string pattern) {
  DirectoryInfo di = new DirectoryInfo(strDir);
  foreach(FileInfo fi in di.GetFiles(pattern) {
    //store file data
  }
  foreach(DirectoryInfo diInfo in di.GetDirectories()) {
    CollectFiles(diInfo);
  }
}

Becomes ugly because you have to include

Check If This Is A Special Folder And Deal With It And Its Child Folders Differently ();

Fair enough Microsoft, to have a folder that could exist anywhere, on a remote PC, on a server etc. But really what is wrong with the UNIX/Linux way, use links to folder and if the destination physical folder has to move, alter the link. Then you can itterate them in a nice neat function treating them all as if ordinary folders.

Basinger answered 12/9, 2012 at 13:43 Comment(0)
J
1

I don't have enough reputation to add a comment so as a +1 to BobRassler's answer, string comparisons might be more useful.

bool isSpecialFolder = false;
DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(tbx_FolderName.Text, fileName));

foreach (Environment.SpecialFolder specialFolder in Enum.GetValues(typeof(Environment.SpecialFolder)))
{
    if (directoryInfo.FullName.ToString()
            .ToLower() ==
        Environment.GetFolderPath(specialFolder)
            .ToLower())
    {
        isSpecialFolder = true;
        break;
    }
}

if (isSpecialFolder)
{
    // something 
}
else
{
    // something else
}
Jahdai answered 14/11, 2022 at 12:49 Comment(2)
Or you should call Equals with StringComparison.OrdinalIgnoreCase instead of converting both strings. That's much faster.Oriente
Yeah, I was also wondering how this handles i18n and what happens if the languages are different (like, you get MyDocuments from a config on a different language system). And as you said, of course the whole case-aware-but-not-sensitive thing makes it more complicated to think about it :-)Astatine
A
0

Use a reflection to get all values from that enum, like here http://geekswithblogs.net/shahed/archive/2006/12/06/100427.aspx and check against collection of generated paths you get.

Alimentary answered 20/8, 2011 at 11:14 Comment(1)
The link's dead Jim. The link's dead…Astatine
A
0

I ended up using it this way:

public static bool IsSpecialFolder(DirectoryInfo directoryInfo, out Environment.SpecialFolder? _specialFolder) {
    bool isSpecialFolder = false;
    _specialFolder = null;

    string directoryInfo_FullPath = directoryInfo.FullName;
    foreach (Environment.SpecialFolder specialFolder in Enum.GetValues(typeof(Environment.SpecialFolder))) {
        var specialFolder_FullPath = Environment.GetFolderPath(specialFolder);

        if (string.Equals(directoryInfo_FullPath, specialFolder_FullPath, StringComparison.OrdinalIgnoreCase)) {
            isSpecialFolder = true;
            _specialFolder  = specialFolder;
            break;
        }
    }

    return isSpecialFolder;
}

If handling strings from dubious sources (the user :-) ), there are three caveats to keep in mind:

  • Path.Combine vs. Path.Join, since they handle absolute paths (or paths that look like absolute paths) differently.
  • Path.GetFullPath, which takes a string an produces the full and normalized version of it.
  • GetFolderPath can return an empty string, which generates a System.ArgumentException: 'The path is empty. (Parameter 'path')' when used for creating a DirectoryInfo.

I like to keep this logic outside the method, but I am not sure if the OrdinalIgnoreCase or any other normalization is still necessary. I guess not.

P.S.: I think in modern lingo the method should be called TrySpecialFolder or something :-)

Astatine answered 2/1, 2023 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.