2012-06-20 48 views
5

En mi programa C# tengo que buscar directorios. Así que utilizo el método System.IO.Directory.GetFiles(directory) y funciona bien cuando el directorio es un directorio real como "C: \ Program File" pero cuando es un directorio virtual (por ejemplo: librairie directory), el valor del directorio es el siguiente: ":: {031E4825 -7B94-4dc3-B131-E946B44C8DD5} \ Pictures.library-ms "y no sé cómo buscarlo.¿Cómo puedo explorar una carpeta virtual local en C#?

Respuesta

1

necesita traducir la ruta de acceso virtual a una física, trate de:

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

Es posible que desee leer sobre DirectoryInfo. Si eso no sirve de nada, le daría prueba este lugar:

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

¿Qué es "Server.MapPath"? Las referencias de MSDN que pude encontrar para MapPath están todas dentro de System.Web ... OP no especificó que esta era una aplicación web, además, de la descripción no se parece en nada a la web. – poncha

+1

'OP no especificó esto era una aplicación web'. Él no especificó que tampoco es ... – dtsg

+1

Tiene razón, no lo hizo, pero el ejemplo específico que dio fue una ruta virtual a una biblioteca del sistema, que está relacionada dudosamente con la web ... – poncha

1

Sé que esto es una locura de edad, pero en caso de que alguien quiere la solución, esto es lo que he descubierto en el último medio día buscando en este . Existen varias soluciones que pueden hacer que obtenga the folder names if you give it the path to the Virtual Folder's XML location, pero nada de lo que he visto lo lleva al ::{031E4825-....}. Hubo un hint in another question's answer para usar el ejemplo KnownFoldersBrowser de WindowsAPICodePack. Así que leí a través del código fuente en eso y han llegado con lo siguiente:

Aquí está el DialogBox que estaba usando para obtener carpetas, y he permitido para AllowNonFileSystemItems, lo que permite selecciones de carpetas de Bibliotecas:

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

Luego repito más de allSpecialFolders para encontrar este mismo ::{031E4825-...} que es el nombre de Parsing para SpecialFolder (sí, probablemente una forma más elegante). Después de eso, utilice el código XML lectura de otras soluciones (I used a CodeProject example that did the same thing) para obtener las carpetas en la carpeta de biblioteca:

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

Espero que esto ayude a alguien en el futuro!

+1

Alternativamente, ['Shell.Application.NameSpace (" :: {031E4825 -....} ") .Items'] (http://blogs.msdn.com/b/oldnewthing /archive/2013/02/04/10390725.aspx). Si solo está buscando bibliotecas, puede usar la [API de bibliotecas] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd758094 (v = vs.85) .aspx). – Mitch

Cuestiones relacionadas