How to get all files in StorageFolder in Windows Phone Runtime?
I want to get all files in a folder and its subfolders. but a flat query like this:
var allFiles = await myFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName);
throws an exception ArgumentException
:
The first random error of type "System.ArgumentException" has occurred
Additional information: The value is not in the expected range.
before I ask for subfolders one by one, is there no other way?
You want all files and folder to be a child of the root folder, not just a shallow enummeration. For most folders, the only way to list all content and the contents of its subfolders is:
- Use
StorageFolder.GetFilesAsync()
for files - Use
StorageFolder.GetFoldersAsync()
to extract all subfolders - Repeat the recursion for all the subfolders you find in step 2.
There is a workaround for this if you are looking for a specific type of media. Instructions are here . These several combinations of CommonFile / FolderQuery locations and options will give a deep device search for the media and return ordered results.
Use CommonFileQuery.OrderByName
This is a deep query, so the result will contain all files from all subfolders AND IT WORKS!;)
MSDN says what you get System.ArgumentException
if:
You specified a value other than
DefaultQuery
, from enumerationCommonFileQuery
for a folder that is not a library folder.
https://msdn.microsoft.com/en-us/library/windows/apps/BR211591.aspx
This is strange! Looks like an error in the GetFilesAsync method with all CommaonFileQuery parameters except DefaultQuery
. It works great with DefaultQuery.
var allFiles = await myFolder.GetFilesAsync(CommonFileQuery.DefaultQuery);
Hope this helps!
I had the same problem, it was solved by preloading the file paths:
private static List<string> mContentFilenames = new List<string>();
private static void preloadContentFilenamesRecursive(StorageFolder sf)
{
var files = sf.GetFilesAsync().AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
if (files != null)
{
foreach (var f in files)
{
mContentFilenames.Add(f.Path.Replace('\\','/'));
}
}
var folders = sf.GetFoldersAsync().AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
if (folders != null)
{
foreach (var f in folders)
{
preloadContentFilenamesRecursive(f);
}
}
}
private static void preloadContentFilenames()
{
if (mContentFilenames.Count > 0)
return;
var installed_loc = Windows.ApplicationModel.Package.Current.InstalledLocation;
var content_folder = installed_loc.GetFolderAsync("Content").AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
if (content_folder != null)
preloadContentFilenamesRecursive(content_folder);
}
private static bool searchContentFilename(string name)
{
var v = from val in mContentFilenames where val.EndsWith(name.Replace('\\', '/')) select val;
return v.Any();
}
Not sure why downvoted, there is no other way to get complete list of files in WP8.1. MSFT corrupts its apis from version to version for some strange reason. Some calls now return "not implemented".