4

Ok so I have a simple uwp app where I am trying to get data from KnownFolders.VideoLibrary and to make it faster I am using indexing with QueryOptions. Strangely on the first load of the page I dont get any error, but when I try to drill into another folder and navigate to the same page again I get this Com Exception

Error is of type System.Runtime.InteropServices.COMException

Error HRESULT E_FAIL has been returned from a call to a COM component

FillFolders method in my ViewModel**

private async Task FillUpFolders()
    {
        uint index = 0, stepSize = 5;
        //on the first load of the LibraryPage I dont get any exception
        //but on the 2nd load, I get exception on the line below.
        var VideoQuery = FileHelper.GetVideoFoldersQuery(MainFolder, 200);
        IReadOnlyList<StorageFolder> folders = await VideoQuery.GetFoldersAsync(index, stepSize);
        index += 5;
        while (folders.Count != 0)
        {
            var folderTask = VideoQuery.GetFoldersAsync(index, stepSize).AsTask();
            foreach (StorageFolder folder in folders)
            {
                var vv = new Folder
                {
                    MyStorageFolder = folder,
                    Title = folder.DisplayName,
                    Thumbnail = new BitmapImage(new Uri("ms-appx:///Assets/FolderIcon.png")),
                    MyStretch = Windows.UI.Xaml.Media.Stretch.Uniform
                };
                Source.Add(vv);
            }
            folders = await folderTask;
            index += 5;
        }
    }

Video Files Query method

internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
    {
        if (videoFolderOptions is null)
        {
            videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery)
            {
                IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties//check sort order later               
            };
            videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
        }
        return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
    }

I am providing my project on a github repo so anyone can easily reproduce the problem and easily can analyze it.

https://github.com/touseefbsb/UWPStorageFolderBug

StackTrace

" at Windows.Storage.StorageFolder.CreateFolderQueryWithOptions(QueryOptions queryOptions)\r\n at Fluent_Video_Player.Helpers.FileHelper.GetVideoFoldersQuery(StorageFolder Folder, UInt32 thumbnailRequestedSize)\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__11.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.ViewModels.LibraryViewModel.d__9.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at Fluent_Video_Player.Views.LibraryPage.d__5.MoveNext()"

Steps to reproduce

  1. Clone the repo
  2. open the solution in VS 2017
  3. Run the app
  4. Go to Library page from left navigation menu ( notice no error here )
  5. click on any folder to drill into it
  6. Now you will get this exception.

Note : I tried to do ConfigureAwait(false) with Fill() method on LibraryPage.xaml.cs and FillUpFolders() and FillUpFiles() methods within the viewmodel this lead to Marshall thread which I was not able to solve even after using Dispather helper

Romasz
  • 29,662
  • 13
  • 79
  • 154
Muhammad Touseef
  • 4,357
  • 4
  • 31
  • 75

1 Answers1

2

Can you remove the option

IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties

from the function GetVideoFoldersQuery, so that it looks like this

internal static StorageFolderQueryResult GetVideoFoldersQuery(StorageFolder Folder, uint thumbnailRequestedSize)
{
    if (videoFolderOptions is null)
    {
        videoFolderOptions = new QueryOptions(CommonFolderQuery.DefaultQuery);
        videoFolderOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
    }
    return Folder.CreateFolderQueryWithOptions(videoFolderOptions);
}

With this version, I find that it does not crash with the same error as previously.

I do get an InvalidCastException in the function GetDisplayForFile, but I think that is quite different problem.

Edit

I inserted the following block of test code into the function OnNavigateTo in your code:

var    folder = KnownFolders.VideosLibrary;

// Define two different QueryOptions
var    qo_1   = new QueryOptions(CommonFolderQuery.DefaultQuery);
var    qo_2   = new QueryOptions(CommonFolderQuery.DefaultQuery)
                    {
                      IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties
                    };

// Query folder and then query the files and subfolders
// using the first QueryOptions qo_1
var    fq_1   = folder.CreateFolderQueryWithOptions ( qo_1 ) ;
var    fo_1   = await fq_1.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_1 )
{
  var f_1  = subfold.CreateFileQueryWithOptions ( qo_1 ) ;
  var sf_1 = subfold.CreateFolderQueryWithOptions ( qo_1 ) ;
}

// Query folder and then query the files and subfolders
// using the first QueryOptions qo_2
var    fq_2   = folder.CreateFolderQueryWithOptions ( qo_2 ) ;
var    fo_2   = await fq_2.GetFoldersAsync ( 0, 5 ) ;
foreach ( var subfold in fo_2 )
{
  var f_2  = subfold.CreateFileQueryWithOptions ( qo_2 ) ;
  var sf_2 = subfold.CreateFolderQueryWithOptions ( qo_2 ) ;
}

It defines two different QueryOption objects and then performs a two level query with each of them.

The first one works fine.
The second one crashes on querying at the second level.

This looks to me like a bug which you should report to Microsoft. You might get more help in a Microsoft Forum.

Phil Jollans
  • 3,605
  • 2
  • 37
  • 50
  • if I use Folder.CreateFolderQuery() and not CreateFolderQueryWithOptions() then it doesnt crash, but this is just a temporary fix, the main question remains , why does it crash? and if there is a valid problem then it should crash even on the first load. – Muhammad Touseef Mar 29 '18 at 23:36
  • On the first load, you query the subfolders of the predefined object **KnownFolders.VideosLibrary**. This doesn't crash. In the second case you query the subfolders using the folder objects returned by the first query. These object behave differently. – Phil Jollans Mar 30 '18 at 05:38
  • nop I also suspected that, I tried to use a sub folder in first run as well and it didnt crash – Muhammad Touseef Mar 30 '18 at 07:43
  • That is not my experience. See the edit I made to my answer. – Phil Jollans Mar 30 '18 at 07:53
  • yeah u r right, but if u to try to get do VideoLibrary.GetFoldersAsync()[0] and just take first folder without query anything, then if u try to put that first folder to the query it will not crash even if it is not a KnownFolder, but U guess u r right it is a problem with the api. – Muhammad Touseef Mar 30 '18 at 08:05
  • I guess I will have to use it without the Indexing for the folders. – Muhammad Touseef Mar 30 '18 at 08:05