How can I read the contents of file in the share target callback

Category: windows metro apps native

Question

ckkashyap on Wed, 03 Apr 2013 14:43:55


Hi,

I am trying to write a Windows Store app that implements the share target. Other apps can share  "files" with my app and I'd like to read the contents of the file. I checked the sample where share target activation code is implemented  - What I gather is that, we get the "IStorageItem". How can I use that to read the contents of the file. Should I just extract the name and do the reading routine or can I convert it to a IStorageFile somehow?

        if (shareOperation->Data->Contains(StandardDataFormats::StorageItems))
        {
            dataPackageTasks.push_back(create_task(shareOperation->Data->GetStorageItemsAsync()).then(
                [this](task<IVectorView<IStorageItem^>^> itemsTask)
            {
                try
                {
                    sharedStorageItems = itemsTask.get();
                }
                catch (Exception^ ex)
                {
                    NotifyUserBackgroundThread("Failed GetStorageItemsAsync - " + ex->Message, NotifyType::ErrorMessage);
                }
            }));

regards,

Kashyap

Replies

MikeBMcL on Wed, 03 Apr 2013 21:23:21


I have not tried this code so I can't say for sure that it'll work correctly, but you could try something like this:

	std::vector<task<void>> dataPackageTasks;

	shareOperation->ReportStarted();

	if (shareOperation->Data->Contains(StandardDataFormats::StorageItems))
	{
		dataPackageTasks.push_back(create_task(shareOperation->Data->GetStorageItemsAsync()).then(
			[this, &shareOperation](task<IVectorView<IStorageItem^>^> itemsTask)
		{
			IVectorView<IStorageItem^>^ sharedStorageItems;

			try
			{
				sharedStorageItems = itemsTask.get();
			}
			catch (Exception^ ex)
			{
				shareOperation->ReportError(L"Error retrieving the shared files. Please try again.");
				NotifyUserBackgroundThread("Failed GetStorageItemsAsync - " + ex->Message, NotifyType::ErrorMessage);
			}

			shareOperation->ReportDataRetrieved();

			std::vector<task<void>> processFiles;
			for (uint32 i = 0; i < sharedStorageItems->Size; ++i)
			{
				auto item = sharedStorageItems->GetAt(i);
				if (item->IsOfType(StorageItemTypes::File))
				{
					auto file = safe_cast<IStorageFile^>(item);
					processFiles.push_back(
						create_task(file->OpenReadAsync()).then(
						[this](IRandomAccessStreamWithContentType^ stream)
					{
						// Read contents and do whatever you want.
					}));
				}
			}

			when_all(processFiles.begin(), processFiles.end()).then([] ()
			{
			});
		})); 

	}
	when_all(dataPackageTasks.begin(), dataPackageTasks.end()).then([&shareOperation] ()
	{
		shareOperation->ReportCompleted();
	});

The ReportDataRetrieved call might be in the wrong place; it's possible that you can't report that until you've processed all of the files in which case you would report it right before calling ReportCompleted. I think it's correct as is, but moving that would be something to try in case errors start showing up.

ckkashyap on Thu, 04 Apr 2013 06:40:24


Thanks,

I have the code below. I was hoping to get the contents of the file in the callback from ReadAsync but for some reason I just get one byte "W"!!! What am I doing wrong?

int Processor::processFile(IVectorView<IStorageItem^>^ items){

auto x = items->Size;

for(unsigned int i = 0; i < x; i++ ){
auto f = items->GetAt(i);

auto path = f->IsOfType(StorageItemTypes::File);
StorageFile^ sf =  (StorageFile^)f;


auto n  = sf->DisplayName;

auto readTask = sf->OpenReadAsync();
create_task(readTask).then([this,&x](IRandomAccessStreamWithContentType^  stream)
{
InMemoryRandomAccessStream^ memoryStream = ref new InMemoryRandomAccessStream();
DataWriter^ dataWriter = ref new DataWriter(memoryStream);
dataWriter->WriteString("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");

Buffer^ b=(Buffer^)dataWriter->DetachBuffer();

try{
auto t = stream->ReadAsync(b,10,InputStreamOptions::None);

create_task(t).then([this,&x](IBuffer^ bb)
{
auto str = bb->ToString(); /// Does not seem to contain the file contents as I was expecting
auto raw = str->Data();

//auto l = len;
});
/* auto str = b->ToString();
auto str1 = str->Data();
*/
}catch(Exception^ exp){
int i=0;
i=i+1;
x=i;
}
});

}

return x;
}


Jesse Jiang on Mon, 08 Apr 2013 08:17:06


Hello,

Would you please provide us the whole codes to reproduce this issue,

You can upload your project to SkyDrive
http://skydrive.live.com/

It is not necessary that you send out the whole of your project. We just need a simplest sample to reproduce the problem. You can remove any confidential information or business details from it.

Best regards,
Jesse