如何以编程方式派生Windows下载文件夹“%USERPROFILE%/ Downloads”?

时间:2021-10-27 23:12:54

In .Net we can retreive the paths to 'special folders', like Documents/Desktop etc. Today I tried to find a way to get the path to the 'Downloads' folder, but it's not special enough it seems.

在.Net中,我们可以检索“特殊文件夹”的路径,例如Documents / Desktop等。今天我试图找到一种方法来获取“下载”文件夹的路径,但它看起来并不特别。

I know I can just do 'C:\Users\Username\Downloads', but that seems an ugly solution. So how can I retreive the path using .Net?

我知道我可以做'C:\ Users \ Username \ Downloads',但这似乎是一个丑陋的解决方案。那么如何使用.Net来修复路径呢?

5 个解决方案

#1


0  

The problem of your first answer is it would give you WRONG result if the default Downloads Dir has been changed to [Download1]! The proper way to do it covering all possibilities is

第一个答案的问题是,如果默认的下载目录已更改为[Download1],它会给你错误的结果!覆盖所有可能性的正确方法是

using System;
using System.Runtime.InteropServices;

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

    [Flags] public enum KnownFolderFlags : uint { SimpleIDList = 0x00000100
        , NotParentRelative = 0x00000200, DefaultPath = 0x00000400, Init = 0x00000800
        , NoAlias = 0x00001000, DontUnexpand = 0x00002000, DontVerify = 0x00004000
        , Create = 0x00008000,NoAppcontainerRedirection = 0x00010000, AliasOnly = 0x80000000
    }
    public static string GetPath(string RegStrName, KnownFolderFlags flags, bool defaultUser) {
        IntPtr outPath;
        int result = 
            SHGetKnownFolderPath (
                new Guid(RegStrName), (uint)flags, new IntPtr(defaultUser ? -1 : 0), out outPath
            );
        if (result >= 0)            {
            return Marshal.PtrToStringUni(outPath);
        } else {
            throw new ExternalException("Unable to retrieve the known folder path. It may not "
                + "be available on this system.", result);
        }
    }

}   

To test it, if you specifically desire your personal download dir, you flag default to false -->

要测试它,如果您特别需要个人下载目录,则将默认值标记为false - >

using System.IO;
class Program    {
    [STAThread]
    static void Main(string[] args)        {
        string path2Downloads = string.Empty;
        path2Downloads = 
            cGetEnvVars_WinExp.GetPath("{374DE290-123F-4565-9164-39C4925E467B}", cGetEnvVars_WinExp.KnownFolderFlags.DontVerify, false);
        string[] files = { "" };
        if (Directory.Exists(path2Downloads)) {
            files = Directory.GetFiles(path2Downloads);
        }
    }//Main
}

Or just one line Environment.ExpandEnvironmentVariables()--> (the simplest solution).

或者只是一行Environment.ExpandEnvironmentVariables() - >(最简单的解决方案)。

using System.IO;
class Program    {
/* https://ss64.com/nt/syntax-variables.html */
    [STAThread]
    static void Main(string[] args)        {
        string path2Downloads = string.Empty;
        string[] files = { "" };
        path2Downloads = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\Downloads");
        if (Directory.Exists(path2Downloads)) {
            files = Directory.GetFiles(path2Downloads);
        }
    }//Main
}

#2


21  

Yes it is special, discovering the name of this folder didn't become possible until Vista. .NET still needs to support prior operating systems. You can pinvoke SHGetKnownFolderPath() to bypass this limitation, like this:

是的,这是特别的,发现这个文件夹的名称直到Vista才成为可能。 .NET仍然需要支持以前的操作系统。你可以用SHvetKnownFolderPath()来绕过这个限制,如下所示:

using System.Runtime.InteropServices;
...

public static string GetDownloadsPath() {
    if (Environment.OSVersion.Version.Major < 6) throw new NotSupportedException();
    IntPtr pathPtr = IntPtr.Zero;
    try {
        SHGetKnownFolderPath(ref FolderDownloads, 0, IntPtr.Zero, out pathPtr);
        return Marshal.PtrToStringUni(pathPtr);
    }
    finally {
        Marshal.FreeCoTaskMem(pathPtr);
    }
}

private static Guid FolderDownloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHGetKnownFolderPath(ref Guid id, int flags, IntPtr token, out IntPtr path);

#3


0  

I used the below code and it works for .net 4.6 with Windows 7 and above. The below code gives the user profile folder path -> "C:\Users\<username>"

我使用下面的代码,适用于Windows 7及更高版本的.net 4.6。下面的代码给出了用户配置文件文件夹路径 - >“C:\ Users \

string userProfileFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

Next to access the downloads folder just combine additional path strings as below:

在访问downloads文件夹旁边,只需合并其他路径字符串,如下所示:

string DownloadsFolder = userProfileFolder + "\\Downloads\\";

Now, the final result will be

现在,最终结果将是

"C:\Users\<username>\Downloads\"

Hope it saves time for someone in the future.

希望它为将来的某个人节省时间。

#4


-1  

try:

尝试:

Dim Dd As String = Environment.GetFolderPath(Environment.SpecialFolder.Favorites)
Dim downloD As String = Dd.Replace("Favorites", "Downloads")
txt1.text = downLoD

its just a trick , not solution .

它只是一个技巧,而不是解决方案。

#5


-3  

For VB, try...

对于VB,试试......

Dim strNewPath As String = IO.Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)) + "\Downloads\"

#1


0  

The problem of your first answer is it would give you WRONG result if the default Downloads Dir has been changed to [Download1]! The proper way to do it covering all possibilities is

第一个答案的问题是,如果默认的下载目录已更改为[Download1],它会给你错误的结果!覆盖所有可能性的正确方法是

using System;
using System.Runtime.InteropServices;

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

    [Flags] public enum KnownFolderFlags : uint { SimpleIDList = 0x00000100
        , NotParentRelative = 0x00000200, DefaultPath = 0x00000400, Init = 0x00000800
        , NoAlias = 0x00001000, DontUnexpand = 0x00002000, DontVerify = 0x00004000
        , Create = 0x00008000,NoAppcontainerRedirection = 0x00010000, AliasOnly = 0x80000000
    }
    public static string GetPath(string RegStrName, KnownFolderFlags flags, bool defaultUser) {
        IntPtr outPath;
        int result = 
            SHGetKnownFolderPath (
                new Guid(RegStrName), (uint)flags, new IntPtr(defaultUser ? -1 : 0), out outPath
            );
        if (result >= 0)            {
            return Marshal.PtrToStringUni(outPath);
        } else {
            throw new ExternalException("Unable to retrieve the known folder path. It may not "
                + "be available on this system.", result);
        }
    }

}   

To test it, if you specifically desire your personal download dir, you flag default to false -->

要测试它,如果您特别需要个人下载目录,则将默认值标记为false - >

using System.IO;
class Program    {
    [STAThread]
    static void Main(string[] args)        {
        string path2Downloads = string.Empty;
        path2Downloads = 
            cGetEnvVars_WinExp.GetPath("{374DE290-123F-4565-9164-39C4925E467B}", cGetEnvVars_WinExp.KnownFolderFlags.DontVerify, false);
        string[] files = { "" };
        if (Directory.Exists(path2Downloads)) {
            files = Directory.GetFiles(path2Downloads);
        }
    }//Main
}

Or just one line Environment.ExpandEnvironmentVariables()--> (the simplest solution).

或者只是一行Environment.ExpandEnvironmentVariables() - >(最简单的解决方案)。

using System.IO;
class Program    {
/* https://ss64.com/nt/syntax-variables.html */
    [STAThread]
    static void Main(string[] args)        {
        string path2Downloads = string.Empty;
        string[] files = { "" };
        path2Downloads = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\Downloads");
        if (Directory.Exists(path2Downloads)) {
            files = Directory.GetFiles(path2Downloads);
        }
    }//Main
}

#2


21  

Yes it is special, discovering the name of this folder didn't become possible until Vista. .NET still needs to support prior operating systems. You can pinvoke SHGetKnownFolderPath() to bypass this limitation, like this:

是的,这是特别的,发现这个文件夹的名称直到Vista才成为可能。 .NET仍然需要支持以前的操作系统。你可以用SHvetKnownFolderPath()来绕过这个限制,如下所示:

using System.Runtime.InteropServices;
...

public static string GetDownloadsPath() {
    if (Environment.OSVersion.Version.Major < 6) throw new NotSupportedException();
    IntPtr pathPtr = IntPtr.Zero;
    try {
        SHGetKnownFolderPath(ref FolderDownloads, 0, IntPtr.Zero, out pathPtr);
        return Marshal.PtrToStringUni(pathPtr);
    }
    finally {
        Marshal.FreeCoTaskMem(pathPtr);
    }
}

private static Guid FolderDownloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHGetKnownFolderPath(ref Guid id, int flags, IntPtr token, out IntPtr path);

#3


0  

I used the below code and it works for .net 4.6 with Windows 7 and above. The below code gives the user profile folder path -> "C:\Users\<username>"

我使用下面的代码,适用于Windows 7及更高版本的.net 4.6。下面的代码给出了用户配置文件文件夹路径 - >“C:\ Users \

string userProfileFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

Next to access the downloads folder just combine additional path strings as below:

在访问downloads文件夹旁边,只需合并其他路径字符串,如下所示:

string DownloadsFolder = userProfileFolder + "\\Downloads\\";

Now, the final result will be

现在,最终结果将是

"C:\Users\<username>\Downloads\"

Hope it saves time for someone in the future.

希望它为将来的某个人节省时间。

#4


-1  

try:

尝试:

Dim Dd As String = Environment.GetFolderPath(Environment.SpecialFolder.Favorites)
Dim downloD As String = Dd.Replace("Favorites", "Downloads")
txt1.text = downLoD

its just a trick , not solution .

它只是一个技巧,而不是解决方案。

#5


-3  

For VB, try...

对于VB,试试......

Dim strNewPath As String = IO.Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)) + "\Downloads\"