I want to implement the Share source contract in my WinRT C# Metro app (Windows Release Preview). My app is storing arbitrary files. Not in the filesystem, but instead I get the data over a WCF service as byte[]
. Now I want to share such "files" in my app.
The only possibility I've seen with a standard data format is using the SetStorageItems()
method on the DataPackage
. Thus I'm facing the challenge to convert the data from my byte array to a StorageFile
, which can be shared. I found the StorageFile.CreateStreamedFileAsync()
method and wanted to use it in this way:
// filename: string
// fileContent: byte[]
// ... setting DataPackage title and description ...
DataRequestDeferral deferral = args.Request.GetDeferral();
var file = await Windows.Storage.StorageFile.CreateStreamedFileAsync(filename,
async stream => await stream.WriteAsync(fileContent.AsBuffer()), null);
args.Request.Data.SetStorageItems(new List<IStorageItem> { file });
deferral.Complete();
It compiles fine, but it doesn't work as expected. I've tried the sharing with the standard Mail app. The Mail share view opens and I can create a new mail. The file is shown without thumbnail (as expected), but the e-mail can't be sent. It's showing the sending progress for several minutes and then an error occurs: "Couldn't share {filename} with Mail.". The share charm shows "Something went wrong" and "[...] Mail can't share right now. Try again later.".
It works perfectly when I load the StorageFile
from the file system: the mail opens and is sent within seconds, no problems here. So either I'm using CreateStreamedFileAsync()
wrong or there's a bug in this method, what do you think?
In the callback passed into CreateStreamedFileAsync, you need to actually dispose of the object - that signals to the OS that you are done.
Wrote a complete example here