在我的 C# 程序中,我必须浏览目录。所以我使用该方法
System.IO.Directory.GetFiles(directory)
,当目录是像“C:\ Program File”这样的真实目录但它是虚拟目录(例如:librairie目录)时,它工作得很好,目录值看起来像这样:“::{031E4825-7B94- 4dc3-B131-E946B44C8DD5}\Pictures.library-ms" 我不知道怎么浏览。
问问题
2627 次
2 回答
2
我知道这已经很老了,但如果有人想要解决方案,这就是我在过去半天的调查中发现的。如果您给它提供虚拟文件夹的 XML 位置的路径,那么有几种解决方案可以为您获取文件夹名称,但我没有看到任何东西可以让您从那里获得::{031E4825-....}
。在另一个问题的答案中有使用 WindowsAPICodePack 的 KnownFoldersBrowser 示例的提示。所以我通读了其中的源代码并提出了以下内容:
这是我用来获取文件夹的对话框,我为 AllowNonFileSystemItems 启用了它,它允许选择库文件夹:
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);
}
}
}
}
然后我迭代allSpecialFolders
找到相同::{031E4825-...}
的,它是 SpecialFolder 的 ParsingName(是的,可能是一种更优雅的方式)。之后,使用从其他解决方案中读取的 XML(我使用了一个相同的 CodeProject 示例)来获取该库文件夹中的文件夹:
/// <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;
}
希望这对将来的人有所帮助!
于 2015-07-06T08:45:47.690 回答
1
您需要将虚拟路径转换为物理路径,尝试:
DirectoryInfo directoryInfo = new DirectoryInfo(Server.MapPath("your virtual folder here"));
您可能想阅读DirectoryInfo。如果那没有用,请尝试一下:
DirectoryInfo info = new DirectoryInfo("virtual folder here");
FileInfo[] files = info.GetFiles("*.*", SearchOption.AllDirectories);
于 2012-06-20T09:36:19.987 回答