3
votes

I'm simply trying to attach a file named Document.pdf in the DocumentsLibrary to an email using the Share Charm. My code below works perfectly on the Local Machine:

    private async void OnDataRequestedFiles(DataTransferManager sender, DataRequestedEventArgs e)
    {
        List<IStorageItem> shares = new List<IStorageItem>();
        StorageFile filetoShare = await Windows.Storage.KnownFolders.DocumentsLibrary.GetFileAsync("Document.pdf");

        if (filetoShare != null)
        {
            shares.Add(filetoShare);
            filetoShare = null;
        }

        if (shares != null)
        {
            DataPackage requestData = e.Request.Data;
            requestData.Properties.Title = "Title";
            requestData.Properties.Description = "Description"; // The description is optional.
            requestData.SetStorageItems(shares);
            shares = null;

        }
        else
        {
            e.Request.FailWithDisplayText("File not Found.");
        }
    }

But when I run the exact same code on a Windows Surface Tablet, I get the dreaded "There's nothing to share right now." on the right in the Charms flyout area.

Here's a little more background to help:

  • I'm not looking to use a File Picker...I know the exact file I'm looking for
  • I've enabled the Documents Library Capability in the manifest
  • I've added a File Type Association for pdf in the manifest
  • and yes, the file does exist and is in the Documents Library
  • an email account is properly setup in the Mail App on the surface
  • I can successfully send text emails from the Tablet...just not emails with attachments

Like I said, this works on my Win 8 Development Machine as expected...just not on the Surface. I'm wondering if the Surface has different file or folder permissions?

Thanks for the help...this is driving me CRAZY

3
Does this process work on your Local Machine, when you use a non admin account?AlSki
@AlSki - I believe there is some validity in your comment about using a non-Admin account (I have to write and store the PDF in a different directory)...thanks for pointing this out. I've added an answer that works for the Admin accountiTrout

3 Answers

2
votes

I finally figured it out - the problem was that my Event Handler was async (so that I could use await to set the StorageFile variable).

I solved it by setting the StorageFile variable earlier in my code so that it was already available when the Event Handler was called.

I still have no idea why it worked on my development machine, but no on the WinRT surface...

2
votes

The handler can be an async method. In this case, it is critical to use DataTransferManager. Please refer to the MSDN page specifically for this scenario. For your convenience, the code from the page is copied to here:

private void RegisterForShare()
{
    DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
    dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, 
        DataRequestedEventArgs>(this.ShareStorageItemsHandler);
}

private async void ShareStorageItemsHandler(DataTransferManager sender, 
    DataRequestedEventArgs e)
{
    DataRequest request = e.Request;
    request.Data.Properties.Title = "Share StorageItems Example";
    request.Data.Properties.Description = "Demonstrates how to share files.";

    // Because we are making async calls in the DataRequested event handler,
    // we need to get the deferral first.
    DataRequestDeferral deferral = request.GetDeferral();  

    // Make sure we always call Complete on the deferral.
    try
    {
        StorageFile logoFile = 
            await Package.Current.InstalledLocation.GetFileAsync("Assets\\Logo.png");
        List<IStorageItem> storageItems = new List<IStorageItem>();
        storageItems.Add(logoFile);
        request.Data.SetStorageItems(storageItems);       
    }
    finally
    {
        deferral.Complete();
    }
}

It is critical to place the following statement before any async method is called:

DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView(); 
1
votes

You only have half a second to get the whole job done (getting the file, attaching...etc.). If the half-second deadline occurs you'll get this "driving crazy" message. Consider implementing some resumable logic and replace the message with "the attachment is being prepared please try again in a few seconds" (or else). Your WinRT device might be just slower than your development machine. The latter just does the job before the deadline...