在 C# 中获取下载文件夹?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10667012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:44:35  来源:igfitidea点击:

Getting Downloads Folder in C#?

c#directoryvisual-c#-express-2010

提问by Hunter Mitchell

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\HunterWell, 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?

好的,它在哪里说Users\Hunter嗯,当人们获得我的软件时,名称不是猎人...那么我如何将它转到任何用户的下载文件夹?

采纳答案by Ray

The WinAPI method SHGetKnownFolderPathis the only correct way to retrieve paths to special folders - including the personal ones and the Downloads folder.

WinAPI 方法SHGetKnownFolderPath是检索特殊文件夹路径的唯一正确方法 - 包括个人文件夹和下载文件夹。

There are other ways to get similar results which look promising, but end up with just completely wrong paths on specific systems (for example, combining or hard coding parts of the path or abusing an old registry key). The reason behind that is stated in my CodeProject article, which also lists the full solution. It provides a wrapping class with a support of retrieving all known 94 special folders, and some more goodies.

还有其他方法可以获得类似的结果,看起来很有希望,但最终在特定系统上得到完全错误的路径(例如,组合或硬编码路径的部分或滥用旧的注册表项)。其背后的原因在我的 CodeProject 文章中有说明,其中还列出了完整的解决方案。它提供了一个包装类,支持检索所有已知的 94 个特殊文件夹,以及一些更多的好东西。

For a quick example here, I just pasted a shortened version of the solution, being able to retrieve only the personal special folders, like 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
}

(A fully commented version is found in the CodeProject article linked above.)

(在上面链接的 CodeProject 文章中可以找到完整的评论版本。)

While this was just a nasty wall of code, the surface you have to deal with is pretty simple. Here's an example of a console program outputting the path of the Downloads folder.

虽然这只是一堵令人讨厌的代码墙,但您必须处理的表面非常简单。这是输出下载文件夹路径的控制台程序示例。

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

E.g., just call KnownFolders.GetPath()with the KnownFolderenum value of the folder which path you want to query.

例如,只需KnownFolders.GetPath()使用KnownFolder要查询的文件夹的枚举值调用。

NuGet Package

NuGet 包

If you don't want to go through all this hazzle, just install my NuGet package I recently created. Here's the project site, and here's the gallery link(note that the usage is different and polished, please consult the Usage section on the project site for more information).

如果您不想经历所有这些麻烦事,只需安装我最近创建的 NuGet 包。这里是项目站点,这里是图库链接(注意用法不同,经过打磨,更多信息请查阅项目站点的用法部分)。

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

Usage:

用法:

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

回答by Marduk

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

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

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

有一些带有特殊文件夹路径的变量。

回答by pink li

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.

然后在您的代码中从存储位置读取值。

回答by Guru Dile

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.

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

回答by Leo

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

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

回答by Stefan Steiger

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