2012-06-20 9 views
5

Nel mio programma C# devo sfogliare le directory. Quindi io uso il metodo System.IO.Directory.GetFiles(directory) e funziona bene quando la directory è una directory reale come "C: \ Program File" ma quando è una directory virtuale (ad es. Directory librairie), il valore della directory è simile a questo: ":: {031E4825 -7B94-4dc3-B131-E946B44C8DD5} \ Pictures.library-ms "e non so come sfogliarlo.Come posso esplorare una cartella virtuale locale in C#?

risposta

1

avete bisogno di tradurre il percorso virtuale in uno fisico, provare:

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

si potrebbe desiderare di leggere su DirectoryInfo. Se questo è inutile, dare una prova questo, invece:

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

Che cos'è "Server.MapPath"? I riferimenti MSDN che ho trovato per MapPath sono tutti all'interno di System.Web ... OP non ha specificato che si trattava di un'applicazione Web, inoltre, dalla descrizione non sembra niente di simile al web. – poncha

+1

'OP non ha specificato che questa era un'applicazione web. Non ha specificato che non è neanche ... – dtsg

+1

Hai ragione, non l'ha fatto, ma l'esempio specifico che ha dato era un percorso virtuale per una libreria di sistema, che è probabilmente correlata al web ... – poncha

1

So che questo è pazzo vecchio, ma nel caso in cui qualcuno vuole la soluzione, ecco quello che ho capito nel corso degli ultimi mezza giornata guardare in questo . Ci sono diverse soluzioni là fuori che possono farti ottenere the folder names if you give it the path to the Virtual Folder's XML location, ma nulla di ciò che ho visto ti porta lì da ::{031E4825-....}. C'era un hint in another question's answer per usare l'esempio di KnownFoldersBrowser di WindowsAPICodePack. Così ho letto attraverso il codice sorgente in questo e sono venuto con il seguente:

Ecco il DialogBox mi stava usando per ottenere le cartelle, e ho permesso per AllowNonFileSystemItems, che permette Biblioteca selezioni cartella:

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); 
      } 
     } 
    } 
} 

Quindi eseguo l'iterazione su allSpecialFolders per trovare lo stesso ::{031E4825-...} che è il ParsingName per SpecialFolder (sì, probabilmente un modo più elegante). Dopo di che, utilizzare il codice XML lettura da altre soluzioni (I used a CodeProject example that did the same thing) per ottenere le cartelle in quella cartella libreria:

/// <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; 
    } 

Spero che questo aiuti qualcuno in futuro!

+1

In alternativa, ['Shell.Application.NameSpace (" :: {031E4825 -....} ") .Items'] (http://blogs.msdn.com/b/oldnewthing /archive/2013/02/04/10390725.aspx). Se si cercano solo biblioteche, è possibile utilizzare [API librerie] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd758094 (v = vs.85) .aspx). – Mitch

Problemi correlati