C#通过已知文件夹ID获取位置

12
我想通过文件夹的ID获取它的位置。
例如,下载文件夹的ID为knownfolder:{374DE290-123F-4565-9164-39C4925E467B},当我在Windows资源管理器的地址栏中输入它时,它会将我重定向到下载文件夹。

enter image description here

这里有一个这些ID和相应文件夹的列表(点击此处),因此我可以硬编码这些ID并像这样查找它们,但除非这是唯一的方法,否则我不想这样做。

是否有另一种正确获得我想要的方式?

2个回答

15

这段内容翻译如下: 从这里抄袭。进一步观察后,唯一的方法是使用WinAPI/PInvoke。

public static class KnownFolderFinder
{
    private static readonly Guid CommonDocumentsGuid = new Guid("ED4824AF-DCE4-45A8-81E2-FC7965083634");

    [Flags]
    public enum KnownFolderFlag : uint
    {
        None = 0x0,
        CREATE = 0x8000,
        DONT_VERFIY = 0x4000,
        DONT_UNEXPAND= 0x2000,
        NO_ALIAS = 0x1000,
        INIT = 0x800,
        DEFAULT_PATH = 0x400,
        NOT_PARENT_RELATIVE = 0x200,
        SIMPLE_IDLIST = 0x100,
        ALIAS_ONLY = 0x80000000
    }

    [DllImport("shell32.dll")]
    static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath);

    public static string GetFolderFromKnownFolderGUID(Guid guid)
    {
        return pinvokePath(guid, KnownFolderFlag.DEFAULT_PATH);
    }

    public static void EnumerateKnownFolders()
    {
        KnownFolderFlag[] flags = new KnownFolderFlag[] {
            KnownFolderFlag.None,
            KnownFolderFlag.ALIAS_ONLY | KnownFolderFlag.DONT_VERFIY,
            KnownFolderFlag.DEFAULT_PATH | KnownFolderFlag.NOT_PARENT_RELATIVE,
        };


        foreach (var flag in flags)
        {
            Console.WriteLine(string.Format("{0}; P/Invoke==>{1}", flag, pinvokePath(CommonDocumentsGuid, flag)));
        }
        Console.ReadLine();
    }

    private static string pinvokePath(Guid guid, KnownFolderFlag flags)
    {
        IntPtr pPath;
        SHGetKnownFolderPath(guid, (uint)flags, IntPtr.Zero, out pPath); // public documents

        string path = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath);
        System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath);
        return path;
    }
}

然后您可以这样调用:

var folder = KnownFolderFinder.GetFolderFromKnownFolderGUID(new Guid("374DE290-123F-4565-9164-39C4925E467B");

-4

我认为你正在寻找 Environment.SpecialFolder(System 命名空间):

https://msdn.microsoft.com/en-us/library/system.environment.specialfolder(v=vs.110).aspx

 // Sample for the Environment.GetFolderPath method
using System;

class Sample 
{
    public static void Main() 
{
Console.WriteLine();
Console.WriteLine("GetFolderPath: {0}", 
             Environment.GetFolderPath(Environment.SpecialFolder.System));
}
  }
/*
This example produces the following results:

GetFolderPath: C:\WINNT\System32
*/

2
我想通过文件夹的ID获取其位置。你的方法不适用于已知的文件夹ID。 - rory.ap
2
但是除非这是唯一的方法,否则我不想这样做。有没有其他适当的方法可以得到我想要的东西? - Shannon Holsinger
2
“所以我可以硬编码ID并像这样查找它们,但除非这是唯一的方法,否则我不想这样做。” 这是他不想做的部分。问题的标题是“通过ID获取已知文件夹的位置”。这很明确。 - rory.ap
3
@Brandon -- 为了使用枚举,您必须在设计时知道您有哪些文件夹。你们都没有理解重点:假设运行时动态提供了一个文件夹ID值,如何将其翻译成一个文件夹?拥有文件夹枚举并不能帮助您。 - rory.ap
5
我不明白这如何帮助那位基本上想要一个像 getFolderPathFromGUID(string guid) 这样的函数的提问者。同时请注意,此问题已在 这里 讨论过。 - ken2k
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接