Получение папки с загрузками в C #? [Дубликат]

This question already has an answer here:

How to programmatically derive windows downloads folder “%USERPROFILE%/Downloads”? 5 answers

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

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 Ну, когда люди получают мое программное обеспечение, его имя не охотник ... так как мне сделать, чтобы оно попало туда, где оно находится в любой папке загрузок пользователя?

Ответы на вопрос(6)

Решение Вопроса

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

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

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

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 enum значение папки, путь к которой вы хотите запросить.

NuGet Package

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

PM> Install-Package Syroot.Windows.IO.KnownFolders

Использование:

using System;
using Syroot.Windows.IO;

class Program
{
    static void Main(string[] args)
    {
        string downloadsPath = new KnownFolder(KnownFolderType.Downloads).Path;
        Console.WriteLine("Downloads folder path: " + downloadsPath);
        Console.ReadLine();
    }
}

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

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

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

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

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

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

Затем в своем коде считайте значение, из которого оно хранится.

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

Есть переменные с путем к некоторым специальным папкам.

Ваш ответ на вопрос