2012-06-20 16 views
5

Trong chương trình C# của tôi, tôi phải duyệt các thư mục. Vì vậy, tôi sử dụng phương pháp System.IO.Directory.GetFiles(directory) và nó hoạt động tốt khi thư mục là một thư mục thực như "C: \ Program File" nhưng khi đó là thư mục ảo (ví dụ: librairie directory), giá trị thư mục trông giống như sau: ":: {031E4825 -7B94-4dc3-B131-E946B44C8DD5} \ Pictures.library-ms "và tôi không biết cách duyệt nó.Làm cách nào để duyệt thư mục ảo cục bộ trong C#?

Trả lời

1

Bạn cần phải dịch các con đường ảo vào một vật lý, hãy thử:

DirectoryInfo directoryInfo = new DirectoryInfo(Server.MapPath("your virtual folder here")); 

Bạn có thể muốn đọc lên trên DirectoryInfo. Nếu đó không phải là sử dụng, hãy thử điều này thay vào đó:

DirectoryInfo info = new DirectoryInfo("virtual folder here"); 
FileInfo[] files = info.GetFiles("*.*", SearchOption.AllDirectories); 
+0

"Server.MapPath" là gì? MSDN tài liệu tham khảo tôi có thể tìm thấy cho MapPath là tất cả bên trong System.Web ... OP đã không chỉ định đây là một ứng dụng web, hơn nữa, từ mô tả nó trông giống như web. – poncha

+1

'OP không chỉ định đây là ứng dụng web'. Anh ta không chỉ định rằng nó không phải là một trong hai ... – dtsg

+1

Bạn nói đúng, anh ta đã không làm, nhưng ví dụ cụ thể mà anh ta đưa ra là một đường dẫn ảo đến một thư viện hệ thống, đó là nghi ngờ liên quan đến web ... – poncha

1

Tôi biết điều này là điên rồ, nhưng trong trường hợp ai đó muốn giải pháp, đây là những gì tôi đã tìm ra trong nửa ngày qua xem xét điều này . Có một số giải pháp có thể giúp bạn có được the folder names if you give it the path to the Virtual Folder's XML location, nhưng không có gì tôi thấy được ở đó từ ::{031E4825-....}. Có một số hint in another question's answer để sử dụng ví dụ KnownFoldersBrowser của WindowsAPICodePack. Vì vậy, tôi đọc qua các mã nguồn trong đó và đã đưa ra như sau:

Dưới đây là DialogBox Tôi đã sử dụng để có được các thư mục, và tôi đã kích hoạt nó cho AllowNonFileSystemItems, cho phép lựa chọn thư mục Library:

Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog dlg = new Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog(); 
dlg.Title = "Pick Folder"; 
dlg.IsFolderPicker = true; 
dlg.InitialDirectory = Environment.SpecialFolder.Personal.ToString(); // If default setting does not exist, pick the Personal folder 

dlg.AddToMostRecentlyUsedList = false; 
dlg.AllowNonFileSystemItems = true; 
dlg.DefaultDirectory = dlg.InitialDirectory; 
dlg.EnsurePathExists = true; 
dlg.EnsureFileExists = false; 
dlg.EnsureReadOnly = false; 
dlg.EnsureValidNames = true; 
dlg.Multiselect = true; 
dlg.ShowPlacesList = true; 

if (dlg.ShowDialog() == Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult.Ok) 
{ 
    foreach (string dirname in dlg.FileNames) 
    { 
     var libFolders = ExpandFolderPath(dirname); 
     if (libFolders == null) 
     { 
      MessageBox.Show("Could not add '" + dirname + "', please try another."); 
     } 
     else 
     { 
      foreach (string libfolder in libFolders) 
      { 
       DoWork(libfolder); 
      } 
     } 
    } 
} 

Tôi sau đó lặp lại trên allSpecialFolders để tìm cùng một số ::{031E4825-...} là ParsingName cho SpecialFolder (vâng, có thể là một cách thanh lịch hơn). Sau đó, sử dụng XML đọc từ các giải pháp khác (I used a CodeProject example that did the same thing) để có được các thư mục trong thư mục thư viện:

/// <summary>Gets the folders associated with a path</summary> 
    /// <param name="libname"></param> 
    /// <returns>Folder, or List of folders in library, and null if there was an issue</string></returns> 
    public List<string> ExpandFolderPath(string foldername) 
    { 
     List<string> dirList = new List<string> { }; 
     // If the foldername is an existing directory, just return that 
     if (System.IO.Directory.Exists(foldername)) 
     { 
      dirList.Add(foldername); 
      return dirList; 
     } 

     // It's not a directory, so check if it's a GUID Library folder 
     ICollection<IKnownFolder> allSpecialFolders = Microsoft.WindowsAPICodePack.Shell.KnownFolders.All; 
     Regex libguid = new Regex(@"\b([A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12})\b"); 
     var match = libguid.Match(foldername); 
     if (match == null) 
      return null; 

     string fpath = ""; 
     // Iterate over each folder and find the one we want 
     foreach (var folder in allSpecialFolders) 
     { 
      if (folder.ParsingName == foldername) 
      { 
       // We now have access to the xml path 
       fpath = folder.Path; 
       break; 
      } 
     } 
     if (fpath == "") 
     { 
      // Could not find it exactly, so find one with the same prefix, and 
      // replace the filename 
      foreach (var folder in allSpecialFolders) 
      { 
       if (folder.ParsingName.Contains(match.Groups[1].Value)) 
       { 
        string sameDir = System.IO.Path.GetDirectoryName(folder.Path); 
        string newPath = System.IO.Path.Combine(sameDir, match.Groups[2].Value); 
        if (System.IO.File.Exists(newPath)) 
         fpath = newPath; 
        break; 
       } 
      } 
     } 

     if (fpath == "") 
      return null; 

     var intFolders = GetLibraryInternalFolders(fpath); 

     return intFolders.Folders.ToList(); 

    } 


    /// <summary> 
    /// Represents an instance of a Windows 7 Library 
    /// </summary> 
    public class Win7Library 
    { 
     public Win7Library() 
     { 

     } 

     public string Name { get; set; } 

     public string[] Folders { get; set; } 
    } 

    [DllImport("shell32.dll")] 
    static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath); 

    //Handles call to SHGetKnownFolderPath 
    public static string getpathKnown(Guid rfid) 
    { 
     IntPtr pPath; 
     if (SHGetKnownFolderPath(rfid, 0, IntPtr.Zero, out pPath) == 0) 
     { 
      string s = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath); 
      System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath); 

      return s; 
     } 
     else return string.Empty; 
    } 

    private static string ResolveStandardKnownFolders(string knowID) 
    { 
     if (knowID.StartsWith("knownfolder:")) 
     { 
      return getpathKnown(new Guid(knowID.Substring(12))); 
     } 
     else 
     { 
      return knowID; 
     } 
    } 

    private static Win7Library GetLibraryInternalFolders(string libraryXmlPath) 
    { 
     Win7Library newLibrary = new Win7Library(); 
     //The Name of a Library is just its file name without the extension 
     newLibrary.Name = System.IO.Path.GetFileNameWithoutExtension(libraryXmlPath); 

     List<string> folderpaths = new List<string>(); 

     System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); //* create an xml document object. 
     xmlDoc.Load(libraryXmlPath); //* load the library as an xml doc. 

     //Grab all the URL tags in the document, 
     //these point toward the folders contained in the library. 
     System.Xml.XmlNodeList directories = xmlDoc.GetElementsByTagName("url"); 

     foreach (System.Xml.XmlNode x in directories) 
     { 
      //Special folders use windows7 Know folders GUIDs instead 
      //of full file paths, so we have to resolve them 
      folderpaths.Add(ResolveStandardKnownFolders(x.InnerText)); 
     } 

     newLibrary.Folders = folderpaths.ToArray(); 
     return newLibrary; 
    } 

Hope this helps ai đó trong tương lai!

+1

Ngoài ra, ['Shell.Application.NameSpace (" :: {031E4825 -....} ") .Items'] (http://blogs.msdn.com/b/oldnewthing /archive/2013/02/04/10390725.aspx). Nếu bạn chỉ tìm kiếm thư viện, bạn có thể sử dụng [Libraries API] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd758094 (v = vs.85) .aspx). – Mitch

Các vấn đề liên quan