Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从windows media库获取目录列表_C#_.net_Windows - Fatal编程技术网

C# 从windows media库获取目录列表

C# 从windows media库获取目录列表,c#,.net,windows,C#,.net,Windows,是否有任何方法可以通过编程方式查找当前在Windows媒体库上设置的目录列表 例如:假设我有以下图书馆(我为葡萄牙语道歉,但你会明白的): 如何以编程方式获取视频库中列出的三个目录路径 D:\Filmes D:\Series D:\Videos 我差点就到了,但这不是我想要的。到目前为止,我的另一个选择是尝试直接从Windows注册表中查找它 using System.Runtime.InteropServices; using System.Diagnostics; using Sy

是否有任何方法可以通过编程方式查找当前在Windows媒体库上设置的目录列表

例如:假设我有以下图书馆(我为葡萄牙语道歉,但你会明白的):

如何以编程方式获取视频库中列出的三个目录路径

D:\Filmes
D:\Series
D:\Videos
我差点就到了,但这不是我想要的。到目前为止,我的另一个选择是尝试直接从Windows注册表中查找它

 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

 }
使用System.Runtime.InteropServices;
使用系统诊断;
使用System.IO;
使用System.Xml;
[DllImport(“shell32.dll”)]
私有静态extern int SHGetKnownFolderPath([Marshallas(UnmanagedType.LPStruct)]Guid rfid、uint dwFlags、IntPtr hToken、ref IntPtr ppszPath);
public void GetVideoLibraryFolders()
{
var pathPtr=默认值(IntPtr);
var videoLibGuid=新Guid(“491E922F-5643-4AF4-A7EB-4E7A138D8174”);
SHGetKnownFolderPath(videoLibGuid,0,IntPtr.Zero,ref-pathPtr);
字符串路径=Marshal.PtrToStringUni(路径ptr);
FreeCoTaskMem元帅(pathPtr);
List foldersInLibrary=新列表();
使用(XmlReader=XmlReader.Create(path))
{
while(reader.ReadToFollowing(“simpleLocation”))
{
reader.ReadToFollowing(“url”);
添加(reader.ReadElementContentAsString());
}
}
for(int i=0;i
那么,我是怎么做到的

首先,在
shell32.dll
库中有一个函数
SHGetKnownFolderPath
,它返回提供GUID()的文件夹路径。 Windows上的每个已知文件夹都有一系列的GUI

“491E922F-5643-4AF4-A7EB-4E7A138D8174”
视频库
文件夹的ID

但有一个问题!该函数将返回以下路径:
%appdata%\Microsoft\Windows\Libraries\Videos.library ms

如果您尝试使用类似于
Directory.GetDirectories
的方法访问该文件夹,您将得到一个
DirectoryNotFoundException
。发生了什么?问题是:
视频。图书馆ms
不是文件夹!这是一个XML文件。如果用文本编辑器打开它,您将看到

在发现它是一个XML文件之后,我所要做的就是读取它,然后我们就有了目录的路径。如果打开xml,您将看到库中的所有文件夹都位于
元素下。因此,您只需读取所有
XML元素,然后读取它们的子元素
,其中的内容包含文件夹本身的路径

虽然这可能是结束,但我幸运地注意到并非每个文件夹路径都被描述为
.library ms
文件中的常规路径;其中一些是用GUID描述的(是的,与我之前链接的相同),并且其中包含
knownfolder
属性。因此,在
的最后一个
中,我在目录列表中搜索包含
knownfolder
属性的元素。对于找到的每一个,我使用
SHGetKnownFolderPath
再次搜索GUID指向的路径,然后用正确的值替换它们的值


就这样

为了未来的研究人员,以下是我提出的代码:

public class MediaLibraries
{
    private static readonly string LibrariesFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Windows\\Libraries";
    private static readonly string VideosLibraryFileName = "Videos.library-ms";

    private static IEnumerable<DirectoryInfo> _videosDirectories;

    public static IEnumerable<DirectoryInfo> VideosDirectories
    {
        get
        {
            if (_videosDirectories != null)
                return _videosDirectories;

            _videosDirectories = new HashSet<DirectoryInfo>();

            var videosLibraryXmlFilePath = Path.Combine(LibrariesFolderPath, VideosLibraryFileName);

            if (!File.Exists(videosLibraryXmlFilePath))
                return _videosDirectories;

            XDocument videosLibraryXml = XDocument.Load(File.OpenRead(videosLibraryXmlFilePath));
            XNamespace ns = videosLibraryXml.Root.Name.Namespace;

            string[] videoFoldersPaths = videosLibraryXml.Root
                                                         .Element(ns + "searchConnectorDescriptionList")
                                                         .Elements(ns + "searchConnectorDescription")
                                                         .Select(scd => scd.Element(ns + "simpleLocation").Element(ns + "url").Value)
                                                         .ToArray();

            _videosDirectories = videoFoldersPaths.Select(v => new DirectoryInfo(v)).AsEnumerable();

            return _videosDirectories;
        }
    }
}
公共类媒体库
{
私有静态只读字符串LibrariesFolderPath=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+“\\Microsoft\\Windows\\Libraries”;
私有静态只读字符串VideosLibraryFileName=“Videos.library ms”;
私有静态IEnumerable\u videosDirectories;
公共静态IEnumerable VideosDirectories
{
得到
{
如果(\u videosDirectories!=null)
返回视频目录;
_videosDirectories=新哈希集();
var videosLibraryXmlFilePath=Path.Combine(LibrariesFolderPath,VideosLibraryFileName);
如果(!File.Exists(videosLibraryXmlFilePath))
返回视频目录;
XDocument videosLibraryXml=XDocument.Load(File.OpenRead(videosLibraryXmlFilePath));
XNamespace ns=videosLibraryXml.Root.Name.Namespace;
字符串[]videoFoldersPaths=videosLibraryXml.Root
.元素(ns+“searchConnectorDescriptionList”)
.元素(ns+“搜索连接描述”)
.Select(scd=>scd.Element(ns+“simpleLocation”).Element(ns+“url”).Value)
.ToArray();
_videosDirectories=videofolderspath.Select(v=>newdirectoryinfo(v)).AsEnumerable();
返回视频目录;
}
}
}
这个想法和@AndreSilva的答案是一样的,尽管我不需要进行互操作


基本上,我已经为库文件夹编写了路径,然后为视频库XML添加了文件名。在那之后,它就是
Linq2XML
magic.

差不多了。。。这将返回我的用户文件夹下的“我的视频”文件夹(及其子目录)