终于到了!
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Xml;
[DllImport("shell32.dll")]
private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, ref IntPtr ppszPath);
public void GetVideoLibraryFolders()
{
var pathPtr = default(IntPtr);
var videoLibGuid = new Guid("491E922F-5643-4AF4-A7EB-4E7A138D8174");
SHGetKnownFolderPath(videoLibGuid, 0, IntPtr.Zero, ref pathPtr);
string path = Marshal.PtrToStringUni(pathPtr);
Marshal.FreeCoTaskMem(pathPtr);
List<string> foldersInLibrary = new List<string>();
using (XmlReader reader = XmlReader.Create(path))
{
while (reader.ReadToFollowing("simpleLocation"))
{
reader.ReadToFollowing("url");
foldersInLibrary.Add(reader.ReadElementContentAsString());
}
}
for (int i = 0; i < foldersInLibrary.Count; i++)
{
if (foldersInLibrary[i].Contains("knownfolder"))
{
foldersInLibrary[i] = foldersInLibrary[i].Replace("knownfolder:{", "");
foldersInLibrary[i] = foldersInLibrary[i].Replace("}", "");
SHGetKnownFolderPath(new Guid(foldersInLibrary[i]), 0, IntPtr.Zero, ref pathPtr);
foldersInLibrary[i] = Marshal.PtrToStringUni(pathPtr);
Marshal.FreeCoTaskMem(pathPtr);
}
}
// foldersInLibrary now contains the path to all folders in the Videos Library
}
那么,我是怎么做到的呢?
首先,有这个功能SHGetKnownFolderPath
in the shell32.dll
库,它返回提供其 GUID 的文件夹的路径(文档 http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx)。
还有一个list http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspxWindows 上每个已知文件夹的 GUID。
"491E922F-5643-4AF4-A7EB-4E7A138D8174"
是 IDVideos_Library
folder.
但有一个问题!该函数将返回此路径:%appdata%\Microsoft\Windows\Libraries\Videos.library-ms
如果您尝试使用以下方法访问该文件夹Directory.GetDirectories
你会得到一个DirectoryNotFoundException
。怎么了?嗯,问题是:Videos.library-ms
不是文件夹!这是一个 XML 文件。如果你用一些文本编辑器打开它,你就会看到。
发现它是一个 XML 文件后,我所要做的就是读取它,我们就得到了目录的路径。如果打开 xml,您将看到 Library 中的所有文件夹都位于<simpleLocation>
元素。所以你只需要阅读所有<simpleLocation>
XML 元素及其子元素<url>
,其中内容包含文件夹本身的路径。
虽然这可能是结束,但我幸运地注意到,并非每个文件夹路径都被描述为.library-ms
文件;其中一些是用 GUID 描述的(是的,我之前链接的那些相同),并且那些具有knownfolder
属性在其中。因此,在最后for
,我在目录列表中搜索具有以下内容的元素knownfolder
属性在其中。对于找到的每一个,我都会使用正确的值替换它们的值,方法是再次搜索 GUID 指向的路径SHGetKnownFolderPath
.
就是这样了!