question

aleibhardt avatar image
0 Votes"
aleibhardt asked aleibhardt edited

StorageApplicationPermissions.FutureAccessList.Entries throwing FileNotFoundException (UWP)

I have a UWP app that i'm seeing rare logs where FutureAccessList.Entrise is throwing a FileNotFoundException. From the logs i've been able to track down the exception to being thrown at this line:

 var accessList = StorageApplicationPermissions.FutureAccessList.Entries

This is the relevant part of the callstack that I'm getting from the logs:

System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
at System.Runtime.InteropServices.McgMarshal.ThrowOnExternalCallFailed(Int32, RuntimeTypeHandle) + 0x20
at __Interop.ComCallHelpers.Call(__ComObject, RuntimeTypeHandle, Int32, Void*) + 0xbe
at __Interop.ForwardComStubs.Stub_3[TThis, TResult](__ComObject, Int32) + 0x37
at Drawboard.Services.FileSystemService.CleanseFutureAccessList(IList`1) + 0x66

This is only happening to a very small percentage of our userbase, however when it does hit, the application becomes unsuable.
Right now, the only mitigation I have for users is to tell them to reinstall the application, which seems to resolve the issue most of the time.

Looking at the documentation, there is no reason that I could see that would cause this exception to be thrown.

Does anyone have any idea what is going on here? For now, I can at least detect this case, and put a prompt up to the user suggesting they reinstall the app, but obviously this is just a temporary stop gap, and it would be great to be able to solve this problem without needing the user to perform a reinstall.

windows-uwp
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

We can't reproduce your problem with above code, derive from the error description, it looks throw exception when call GetItemAsync(token) method, It will if you delete the file but not remove the token. For this scenario, we suggest you use try catch block to handle above.

 try
 {
     // Will throw if it no longer exists
     await accessList.GetItemAsync(token);
 }
 catch (Exception)
 {
     accessList.Remove(token);
 }



1 Vote 1 ·

Hi Nico,

Thanks for your response. The issue does not reproduce reliably. However, once it does reproduce it makes our application completely useless for most users, as they can't access the file system.

I did a bit more digging and now have a little bit more information on how to reproduce this issue. The first part was that I found out where in the OS the future access list entries are being stored. For our app they are stored at:
HKCU\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\SystemAppData\DRAWBOARD.DRAWBOARDPDF_gqbn7fs4pywxm\PersistedStorageItemTable\ManagedByApp\

We had some customers that were reproducing this issue, so I had them send me the registry file from the above file.

With that, i found that if I delete the following entry, "LastUpdatedTime" then the exception starts throwing.

I've been able to work around the issue by calling the following function when I hit the issue:

 StorageApplicationPermissions.FutureAccessList.Clear()

This isn't ideal for the user as it will clear the entire future access list, meaning we can no longer save back to the original source files.

Ideally the platform would detect any corrupt registry entries and remove only the corrupt ones.


0 Votes 0 ·

What's the LastUpdatedTime key you have used?

1 Vote 1 ·
Show more comments

1 Answer

aleibhardt avatar image
0 Votes"
aleibhardt answered aleibhardt edited

I have found a workaround for this issue.

My solution is to call the following line:

 StorageApplicationPermissions.FutureAccessList.Clear()


This function works and clears the future access list completely, deleting the corrupt registry key in the process allowing the rest of the methods to work.

The problem with calling this though is that it removes all of my access to any files that i have saved in the future access list. For my application, this means that the next time a user tries to save a file, they end up being prompted again with a file picker to save the file to a location (kind of a forced save as).

Fortunately, I'm able to completely work around this shortcoming. Our application caches all the tokens in the FutureAccessList for our own purposes. By using this cache, i'm able to call into:

 StorageApplicationPermissions.FutureAccessList.GetItemAsync(token)

Before clearing my list, i load all cached IDirectoryItems into memory.
Now I can clear my list without losing access to any of my files.

After clearing the list, I can go through and add each item back into the FutureAccessList.

Then I simply need to go back through my cache, and update my source tokens with the new tokens and I'm back into a stable state, without losing any future access list.

Note i do think there is something funny going on in the platform here, and somehow the registry is getting corrupted (lastUpdatedTime being deleted), but I can make progress for now.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.