Open winston-de opened 3 years ago
Specifically, this API should integrate with the custom desktop.ini-specified icons for a folder (on Windows 10 desktop). It remains unclear how/if this could work for a standard StorageFile.
FWIW, the object has a WriteAsync
method because it implements IRandomAccessStream
which requires it. Good news is the CanWrite
property is correct.
How do you envision the feature working? For example, you say:
For example a PDF editor could set a thumbnail that consists of a preview of the first page of the document to make it easier for the user to identify the contents of the file
But since the UWP app can only write to files the user has chosen, it can only write thumbnails if they user opens the file in the app (or grants it access to an entire folder, or has broadFilesystemAccess
). Typically the process is driven by the Shell, which will create and cache thumbnails as-needed by using IThumbnailProvider
.
Setting the desktop.ini
content should already be possible I believe, as long as you have access to the folder and are using the CreateFileFromApp
filesystem API.
FWIW, the object has a
WriteAsync
method because it implementsIRandomAccessStream
which requires it. Good news is theCanWrite
property is correct.How do you envision the feature working? For example, you say:
For example a PDF editor could set a thumbnail that consists of a preview of the first page of the document to make it easier for the user to identify the contents of the file
But since the UWP app can only write to files the user has chosen, it can only write thumbnails if they user opens the file in the app (or grants it access to an entire folder, or has
broadFilesystemAccess
). Typically the process is driven by the Shell, which will create and cache thumbnails as-needed by usingIThumbnailProvider
.
Right, if the user creates a document and then saves it, or opens a document, then the application would have the access it needs to create and write a thumbnail.
I was also thinking that maybe a thumbnail provider capability could be provided to universal apps, perhaps using an app service and passing a file access token as an argument.
App manifest:
<uap:Extension Category="windows.appService" EntryPoint="FileService.Preview">
<uap3:AppService Name="com.windows.thumbnails" uap4:SupportsMultipleInstances="true"/>
</uap:Extension>
Code:
namespace FileService
{
public sealed class Preview : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private AppServiceConnection appServiceconnection;
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get a deferral so that the service isn't terminated.
this.backgroundTaskDeferral = taskInstance.GetDeferral();
// Associate a cancellation handler with the background task.
taskInstance.Canceled += OnTaskCanceled;
// Retrieve the app service connection and set up a listener for incoming app service requests.
var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
appServiceconnection = details.AppServiceConnection;
appServiceconnection.RequestReceived += OnRequestReceived;
}
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
AppServiceDeferral messageDeferral = args.GetDeferral();
var message = args.Request.Message;
var returnMessage = new ValueSet();
var file = await SharedStorageAccessManager.RedeemTokenForFileAsync(message["fileAccessToken"] as string);
var thumbnail = await file.GetThumbnailAsync(ThumbnailMode.ListView);
await thumbnail.WriteAsync(await GetThumbnailForFile(file));
messageDeferral.Complete();
}
private Task<IBuffer> GetThumbnailAsync(StorageFile file) {
var content = await file.OpenReadAsync();
IBuffer thumbnail;
// do some magic to make a thumbnail
return thumbnail;
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
if (this.backgroundTaskDeferral != null)
{
// Complete the service deferral.
this.backgroundTaskDeferral.Complete();
}
}
}
}
Sorry for all the edits, I accidently sent this before I finished writing :)
I think adding a thumbnail provider capability is out of scope for this issue. Instead, I think the ask should simply be: Make StorageItemThumbnail.WriteAsync
work for files the app already has access to.
I think adding a thumbnail provider capability is out of scope for this issue. Instead, I think the ask should simply be: Make
StorageItemThumbnail.WriteAsync
work for files the app already has access to.
Ok, I updated the scope table
Sounds very fair, 👍 from me. Nice job!
Setting expectations, this is unlikely to make the priority list (at least in the short-term) but we'll keep it on the backlog and I'll ping a few folks with some ideas. It would require brokering and thus additional complexity.
I was also thinking that maybe a thumbnail provider capability could be provided to universal apps, perhaps using an app service and passing a file access token as an argument.
This isn't feasible because the app would be provided access to arbitrary files on the system without user consent (just open the folder in Explorer, and all the files get sent to the UWP). We could special-case broadFilesystemAccess
or only scope it to folders you have access to, etc. but it's a lot of work for a relatively niche feature. Just use runFullTrust
instead.
I was also thinking that maybe a thumbnail provider capability could be provided to universal apps, perhaps using an app service and passing a file access token as an argument.
This isn't feasible because the app would be provided access to arbitrary files on the system without user consent (just open the folder in Explorer, and all the files get sent to the UWP). We could special-case
broadFilesystemAccess
or only scope it to folders you have access to, etc. but it's a lot of work for a relatively niche feature. Just userunFullTrust
instead.
Makes sense, and I already removed it from the scope.
FYI, the property system API offers PKEY_Thumbnail and PKEY_ThumbnailStream as a way to read and write thumbnails to file formats that support it (.jpg via EXIF, .mp3 via ID3)
Proposal: Allow setting the thumbnail of storage items through StorageItemThumbnail.WriteAsync
Summary
Currently, there is no way for UWP apps to provide thumbnails for storage items. There appears to already be an API for this, StorageItemThumbnail.WriteAsync, however StorageItemThumbnail.CanWrite always seems to be false, and attempting to write to the stream will result in an access denied error. This proposal is to enable setting the thumbnails for items through StorageItemThumbnail.WriteAsync.
Rationale
Scope
StorageItem
's thumbnail using StorageItemThumbnail.WriteAsyncImportant Notes
Open Questions