Getting Downloads Folder in C#?

C#DirectoryVisual C#-Express-2010

C# Problem Overview


I have made some code that will search directories and display files in a listbox.

DirectoryInfo dinfo2 = new DirectoryInfo(@"C:\Users\Hunter\Downloads");
FileInfo[] Files2 = dinfo2.GetFiles("*.sto");
foreach (FileInfo file2 in Files2)
{
     listBox1.Items.Add(file2.Name);
}

I have even tried this:

string path = Environment.SpecialFolder.UserProfile + @"\Downloads";
DirectoryInfo dinfo2 = new DirectoryInfo(Environment.SpecialFolder.UserProfile + path);
FileInfo[] Files2 = dinfo2.GetFiles("*.sto");
foreach (FileInfo file2 in Files2)
{
     listBox1.Items.Add(file2.Name);
}

I get an error though...

Ok, where it says Users\Hunter Well, when people get my software, there name is not hunter...so how do i make it to where it goes to any user's downloads folder?

C# Solutions


Solution 1 - C#

The Downloads folder is a so called "known" folder, together with Documents, Videos, and others.

Do NOT:
  • combine hardcoded path segments to retrieve known folder paths
  • assume known folders are children of the user folder
  • abuse a long deprecated registry key storing outdated paths

Known folders can be redirected anywhere in their property sheets. I've gone into more detail on this several years ago in my CodeProject article.

Do:
  • use the WinAPI method SHGetKnownFolderPath as it is the intended and only correct method to retrieve those paths.

You can p/invoke it as follows (I've provided only a few GUIDs which cover the new user folders):

public enum KnownFolder
{
    Contacts,
    Downloads,
    Favorites,
    Links,
    SavedGames,
    SavedSearches
}

public static class KnownFolders
{
    private static readonly Dictionary<KnownFolder, Guid> _guids = new()
    {
        [KnownFolder.Contacts] = new("56784854-C6CB-462B-8169-88E350ACB882"),
        [KnownFolder.Downloads] = new("374DE290-123F-4565-9164-39C4925E467B"),
        [KnownFolder.Favorites] = new("1777F761-68AD-4D8A-87BD-30B759FA33DD"),
        [KnownFolder.Links] = new("BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968"),
        [KnownFolder.SavedGames] = new("4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4"),
        [KnownFolder.SavedSearches] = new("7D1D3A04-DEBB-4115-95CF-2F29DA2920DA")
    };

    public static string GetPath(KnownFolder knownFolder)
    {
        return SHGetKnownFolderPath(_guids[knownFolder], 0);
    }

    [DllImport("shell32",
        CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
    private static extern string SHGetKnownFolderPath(
        [MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags,
        nint hToken = 0);
}

Here's an example of retrieving the path of the Downloads folder:

string downloadsPath = KnownFolders.GetPath(KnownFolder.Downloads);
Console.WriteLine($"Downloads folder path: {downloadsPath}");

NuGet Package

If you don't want to p/invoke yourself, have a look at my NuGet package (note that the usage is different, please check its README).

Solution 2 - C#

The easiest way is:

Process.Start("shell:Downloads");

If you only need to get the current user's download folder path, you can use this:

I extracted it from @PacMani 's code.

 // using Microsoft.Win32;
string GetDownloadFolderPath() 
{
    return Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "{374DE290-123F-4565-9164-39C4925E467B}", String.Empty).ToString();
}

Solution 3 - C#

Cross-Platform version:

public static string getHomePath()
{
    // Not in .NET 2.0
    // System.Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
    if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
        return System.Environment.GetEnvironmentVariable("HOME");

    return System.Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
}


public static string getDownloadFolderPath()
{
    if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
    {
        string pathDownload = System.IO.Path.Combine(getHomePath(), "Downloads");
        return pathDownload;
    }

    return System.Convert.ToString(
        Microsoft.Win32.Registry.GetValue(
             @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
            ,"{374DE290-123F-4565-9164-39C4925E467B}"
            ,String.Empty
        )
    );
}

Solution 4 - C#

string download = Environment.GetEnvironmentVariable("USERPROFILE")+@"\"+"Downloads";

Solution 5 - C#

http://msdn.microsoft.com/en-us//library/system.environment.specialfolder.aspx

There are the variables with the path to some special folders.

Solution 6 - C#

typically, your software shall have a configurable variable that stores the user's download folder, which can be assigned by the user, and provide a default value when not set. You can store the value in app config file or the registry.

Then in your code read the value from where it's stored.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHunter MitchellView Question on Stackoverflow
Solution 1 - C#RayView Answer on Stackoverflow
Solution 2 - C#Guru DileView Answer on Stackoverflow
Solution 3 - C#Stefan SteigerView Answer on Stackoverflow
Solution 4 - C#LeoView Answer on Stackoverflow
Solution 5 - C#MardukView Answer on Stackoverflow
Solution 6 - C#pink liView Answer on Stackoverflow