有没有什么办法可以编程查找目前在Windows媒体库上设置的目录列表?
例如:假设我有以下图书馆(我为葡萄牙语道歉,但你会明白):
如何以编程方式获取video库中列出的这三个目录path ?
是否可以禁用Windows中的特定智能卡硬件ID的自动智能卡minidriver安装?
本地LDAP服务器在Windows 7上进行开发
将窗口焦点恢复到之前的所有者
为什么Mono在Linux和BSD上运行速度降低了1/3?
如何在使用IO.Directory.EnumerateDirectories时忽略Documents文件夹中的连接点
D:Filmes D:Series D:Videos
这个问题几乎让我在那里,但它不完全是我想要的。 到目前为止,我的select是试图直接从Windowsregistry中查找。
由VB.Net WinForms ClickOnce安装创build的快捷方式没有目标选项卡
使用其IP地址读取远程计算机上的registry – OpenRemoteBaseKey的奇怪行为
与.NET集成的Ruby on Rails的状态是什么?
如何在C#中使用websocket-sharp禁用强制连续帧
Mono / Ubuntu – 冲突的定义
这是最后的!
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,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]),ref pathPtr); foldersInLibrary[i] = Marshal.PtrToStringUni(pathPtr); Marshal.FreeCoTaskMem(pathPtr); } } // foldersInLibrary Now contains the path to all folders in the Videos Library }
那么,我是怎么做到的?
首先, shell32.dll库中有SHGetKNownFolderPath函数,它返回提供GUID( 文档 )的文件夹的路径。 还有Windows上每个已知文件夹的GUID 列表 。
"491E922F-5643-4AF4-A7EB-4E7A138D8174"是Videos_Library文件夹的ID。
但是有一个问题! 该函数将返回此路径: %appdata%MicrosoftwindowsLibrariesVideos.library-ms
如果您尝试使用Directory.GetDirectories方法访问该文件夹,您将得到一个DirectoryNotFoundException 。 怎么了? 那么,问题是: Videos.library-ms不是一个文件夹! 这是一个XML文件。 如果你用一些文本编辑器打开它,你会看到。
在发现它是一个XML文件后,我所要做的只是读取它,我们将有路径到目录。 如果你打开xml,你会发现库中的所有文件夹都在<simpleLocation>元素之下。 所以你只需要读取所有的<simpleLocation> XML元素,然后读取它们的子元素<url> ,其中的内容包含文件夹本身的路径。
虽然这可能是结束,我幸运地注意到,不是每个文件夹路径被描述为.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; } } }
这个想法和AndreSilva的答案是一样的,尽管事实上我不需要经过互操作。
基本上,我已经编写了Libraries文件夹的路径,然后为Video Libraries XML添加了文件名。 之后,这只是Linq2XML魔力。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。