Как загрузить папку загрузки в С#?

Я сделал код, который будет искать каталоги и отображать файлы в списке.

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

Я даже пробовал это:

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);
}

Я получаю сообщение об ошибке, хотя...

Хорошо, где сказано Users\Hunter Ну, когда люди получают мое программное обеспечение, там имя не охотник... так как я могу сделать это там, где он идет, в любую папку для загрузки пользователей?

Ответ 1

Метод WinAPI SHGetKnownFolderPath - единственный правильный способ получить пути к специальным папкам, включая личные и папку "Загрузки".

Существуют и другие способы получения похожих результатов, которые выглядят многообещающими, но заканчиваются просто совершенно неправильными путями в определенных системах (например, комбинирование или жесткое кодирование частей пути или злоупотребление старым ключом реестра). Причина этого указана в моей статье CodeProject, в которой также перечислены полное решение. Он предоставляет класс упаковки с поддержкой поиска всех известных 94 специальных папок и еще нескольких полезных свойств.

Для краткого примера здесь я просто вставил сокращенную версию решения, имея возможность извлекать только личные специальные папки, например Downloads:

using System;
using System.Runtime.InteropServices;

/// <summary>
/// Class containing methods to retrieve specific file system paths.
/// </summary>
public static class KnownFolders
{
    private static string[] _knownFolderGuids = new string[]
    {
        "{56784854-C6CB-462B-8169-88E350ACB882}", // Contacts
        "{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", // Desktop
        "{FDD39AD0-238F-46AF-ADB4-6C85480369C7}", // Documents
        "{374DE290-123F-4565-9164-39C4925E467B}", // Downloads
        "{1777F761-68AD-4D8A-87BD-30B759FA33DD}", // Favorites
        "{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", // Links
        "{4BD8D571-6D19-48D3-BE97-422220080E43}", // Music
        "{33E28130-4E1E-4676-835A-98395C3BC3BB}", // Pictures
        "{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", // SavedGames
        "{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", // SavedSearches
        "{18989B1D-99B5-455B-841C-AB7C74E4DDFC}", // Videos
    };

    /// <summary>
    /// Gets the current path to the specified known folder as currently configured. This does
    /// not require the folder to be existent.
    /// </summary>
    /// <param name="knownFolder">The known folder which current path will be returned.</param>
    /// <returns>The default path of the known folder.</returns>
    /// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
    ///     could not be retrieved.</exception>
    public static string GetPath(KnownFolder knownFolder)
    {
        return GetPath(knownFolder, false);
    }

    /// <summary>
    /// Gets the current path to the specified known folder as currently configured. This does
    /// not require the folder to be existent.
    /// </summary>
    /// <param name="knownFolder">The known folder which current path will be returned.</param>
    /// <param name="defaultUser">Specifies if the paths of the default user (user profile
    ///     template) will be used. This requires administrative rights.</param>
    /// <returns>The default path of the known folder.</returns>
    /// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
    ///     could not be retrieved.</exception>
    public static string GetPath(KnownFolder knownFolder, bool defaultUser)
    {
        return GetPath(knownFolder, KnownFolderFlags.DontVerify, defaultUser);
    }

    private static string GetPath(KnownFolder knownFolder, KnownFolderFlags flags,
        bool defaultUser)
    {
        int result = SHGetKnownFolderPath(new Guid(_knownFolderGuids[(int)knownFolder]),
            (uint)flags, new IntPtr(defaultUser ? -1 : 0), out IntPtr outPath);
        if (result >= 0)
        {
            string path = Marshal.PtrToStringUni(outPath);
            Marshal.FreeCoTaskMem(outPath);
            return path;
        }
        else
        {
            throw new ExternalException("Unable to retrieve the known folder path. It may not "
                + "be available on this system.", result);
        }
    }

    [DllImport("Shell32.dll")]
    private static extern int SHGetKnownFolderPath(
        [MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, IntPtr hToken,
        out IntPtr ppszPath);

    [Flags]
    private enum KnownFolderFlags : uint
    {
        SimpleIDList              = 0x00000100,
        NotParentRelative         = 0x00000200,
        DefaultPath               = 0x00000400,
        Init                      = 0x00000800,
        NoAlias                   = 0x00001000,
        DontUnexpand              = 0x00002000,
        DontVerify                = 0x00004000,
        Create                    = 0x00008000,
        NoAppcontainerRedirection = 0x00010000,
        AliasOnly                 = 0x80000000
    }
}

/// <summary>
/// Standard folders registered with the system. These folders are installed with Windows Vista
/// and later operating systems, and a computer will have only folders appropriate to it
/// installed.
/// </summary>
public enum KnownFolder
{
    Contacts,
    Desktop,
    Documents,
    Downloads,
    Favorites,
    Links,
    Music,
    Pictures,
    SavedGames,
    SavedSearches,
    Videos
}

(Полностью прокомментированная версия находится в статье CodeProject, приведенной выше.)

Хотя это была просто неприятная стена кода, поверхность, с которой вам приходится иметь дело, довольно проста. Вот пример консольной программы, выводящей путь к папке "Загрузки".

private static void Main()
{
    string downloadsPath = KnownFolders.GetPath(KnownFolder.Downloads);
    Console.WriteLine("Downloads folder path: " + downloadsPath);
    Console.ReadLine();
}

Например, просто вызовите KnownFolders.GetPath() с KnownFolder перечисления KnownFolder папки, путь которой вы хотите запросить.

Пакет NuGet

Если вы не хотите проходить через все это, просто установите мой пакет NuGet, который я недавно создал. Здесь сайт проекта, а здесь ссылка на галерею (обратите внимание, что использование отличается и отполировано, более подробную информацию см. В разделе "Использование" на сайте проекта).

Ответ 2

Самый простой способ:

Process.Start("shell:Downloads");

Если вам нужно только получить текущий путь загрузки папки пользователя, вы можете использовать это:

Я извлек его из кода @PacMani.

 // 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();
}

Ответ 3

Кросс-платформенная версия:

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
        )
    );
}

Ответ 5

обычно ваше программное обеспечение должно иметь настраиваемую переменную, в которой хранится папка загрузки пользователя, которая может быть назначена пользователем, и предоставить значение по умолчанию, если оно не установлено. Вы можете сохранить это значение в файле конфигурации приложения или в реестре.

Затем в вашем коде прочитайте значение, из которого оно было сохранено.

Ответ 6

string download = Environment.GetEnvironmentVariable("USERPROFILE")[email protected]"\"+"Downloads";