如何确定 Windows"下载文件夹"路径?



在我的机器上,它在这里:

string downloadsPath = Path.Combine(
   Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
   "Downloads");

但是在同事的机器上,这个文件夹不存在,他的下载文件夹在他的"我的文档"文件夹中。我们都使用Windows 7*.

*Edit:事实上,结果证明他不是在自己的机器上运行应用程序,而是在Windows Server 2003机器上。

Windows没有为Downloads文件夹定义CSIDL,并且无法通过Environment.SpecialFolder枚举获得。

然而,新的Vista已知文件夹API确实用FOLDERID_Downloads的ID定义了它。获取实际值最简单的方法可能是调用SHGetKnownFolderPath

public static class KnownFolder
{
    public static readonly Guid Downloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
}
[DllImport("shell32.dll", CharSet=CharSet.Unicode)]
static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out string pszPath);
static void Main(string[] args)
{
    string downloads;
    SHGetKnownFolderPath(KnownFolder.Downloads, 0, IntPtr.Zero, out downloads);
    Console.WriteLine(downloads);
}

注意pinvoke.net上给出的p/invoke是不正确的,因为它无法使用Unicode字符集。此外,我还利用了这个API返回由COM分配器分配的内存这一事实。上面P/调用的默认编组是使用CoTaskMemFree释放返回的内存,这非常适合我们的需要。

请注意,这是Vista及以上版本的API,不要尝试在XP/2003或更低版本上调用它。

您可以使用Microsoft . net Framework的Windows API代码包。

参考: Microsoft.WindowsAPICodePack.Shell.dll

需要以下命名空间:

using Microsoft.WindowsAPICodePack.Shell;
简单用法:

string downloadsPath = KnownFolders.Downloads.Path;

VB。我使用的Net函数如下

<DllImport("shell32.dll")>
Private Function SHGetKnownFolderPath _
    (<MarshalAs(UnmanagedType.LPStruct)> ByVal rfid As Guid _
    , ByVal dwFlags As UInt32 _
    , ByVal hToken As IntPtr _
    , ByRef pszPath As IntPtr
    ) As Int32
End Function
Public Function GetDownloadsFolder() As String
    Dim Result As String = ""
    Dim ppszPath As IntPtr
    Dim gGuid As Guid = New Guid("{374DE290-123F-4565-9164-39C4925E467B}")
    If SHGetKnownFolderPath(gGuid, 0, 0, ppszPath) = 0 Then
        Result = Marshal.PtrToStringUni(ppszPath)
        Marshal.FreeCoTaskMem(ppszPath)
    End If
    
   'as recommended by Ray (see comments below) 
    Marshal.FreeCoTaskMem(ppszPath)
    Return Result
End Function

在我的程序中,我调用它来移动一些CSV文件到另一个文件夹。

    Dim sDownloadFolder = GetDownloadsFolder()
    Dim di = New DirectoryInfo(sDownloadFolder)
    'Move all CSV files that begin with BE in specific folder
    'that has been defined in a CONFIG file (variable: sExtractPath
    For Each fi As FileInfo In di.GetFiles("BE*.csv")
        Dim sFilename = sExtractPath & "" & fi.Name
        File.Move(fi.FullName, sFilename)
    Next

最新更新