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

我已经做了一些代码,将搜索目录和显示文件在一个列表框。

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

然而,在它说 Users\Hunter-好吧,当人们得到我的软件,他们的名字不是亨特。那么,我如何自动检测用户的下载文件夹?

我试过这个:

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

但我得到了一个错误。

138718 次浏览

通常,您的软件应该有一个可配置的变量,存储用户的下载文件夹,这可以由用户分配,并提供一个默认值时,没有设置。您可以将该值存储在应用程序配置文件或注册表中。

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

下载文件夹是一个所谓的“已知”文件夹,包括文档、视频和其他文件。

不要:

  • 组合硬编码路径段来检索已知的文件夹路径
  • 假设已知文件夹是用户文件夹的子文件夹
  • 滥用存储过时路径的长期废弃的注册表项

已知文件夹可以在其属性表中的任何位置重定向。我在几年前的 我的 CodeProject 文章节目中对此进行了更详细的介绍。

做:

  • 使用 WinAPI 方法 SHGetKnownFolderPath,因为它是检索这些路径的预期且唯一正确的方法。

您可以按照以下方式调用它(我只提供了几个 GUID 来覆盖新的用户文件夹) :

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

下面是一个检索下载文件夹路径的示例:

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

NuGet 软件包

如果你不想调用你自己,看看我的 NuGet 软件包(注意用法不同,请检查它的 README)。

最简单的方法是:

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

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

注:
如果更改了下载文件夹,SHGetKnownFolderPath 将返回 值。

唯一能够返回正确值的就是在 Windows 上读取 shell 文件夹注册表项 374DE290-123F-4565-9164-39C4925E467B

现在您可以使用“ ! 不要使用这个注册表项”,或者您可以得到错误的值。
你决定哪个对你更好。

跨平台版本:

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