【问题标题】:C# get location of knownfolder by IDC#通过ID获取已知文件夹的位置
【发布时间】:2016-09-16 13:11:35
【问题描述】:

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

有一个这些 ID 和相应文件夹 here 的列表,所以我可以硬编码这些 ID 并像这样查找它们,但我不想这样做,除非它是唯一的方法。

还有其他方法可以正确地得到我想要的吗?

【问题讨论】:

    标签: c# windows known-folders


    【解决方案1】:

    here 窃取。进一步看,唯一的方法是使用 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");
    

    【讨论】:

      【解决方案2】:

      我认为您正在寻找 Environment.SpecialFolder(系统命名空间):

      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
      */
      

      【讨论】:

      • "我想通过 ID 获取目录/文件夹的位置。"你的没有使用已知的文件夹 ID...
      • "但我不想这样做,除非它是唯一的方法。还有其他方法可以正确地得到我想要的吗?"
      • "所以我可以硬编码 ID 并像这样查找它们,但我不想这样做,除非这是唯一的方法。"
      • @Brandon -- 为了使用枚举,您必须知道在设计时拥有哪些文件夹。你们都忽略了这一点:给定一个在运行时动态提供的文件夹 ID 值,你如何将其转换为文件夹?拥有文件夹枚举对您没有帮助。
      • 我看不出这对基本上想要 getFolderPathFromGUID(string guid) 这样的功能的 OP 有何帮助。还要注意这是讨论here
      猜你喜欢
      • 1970-01-01
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2011-01-01
      • 1970-01-01
      相关资源
      最近更新 更多