C#按ID获取已知文件夹的位置

Tom*_*ler 11 c# windows known-folders

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

在此输入图像描述

有这些ID和相应的文件夹列表在这里,所以我可以硬编码ID和找一找这样,但我不会想这样做,除非它的唯一途径.

还有另一种方法来正确得到我想要的东西吗?

小智 14

这里偷来.进一步看,唯一的方法是使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以调用这样的东西:

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