locked
Trynig to save a file in desired folder

    Question

  • Am developing an application using C++ xaml.

    Am trying to save a file in a folder which is in DocumentsLibrary. Can anyone help me in this scenario.

    When am trying to do this am getting an error:

    "an enclosing-functional local variable cannot be referenced in a lambda body unless it is in  the capture list."

    Can any one help me in this scenario.

    Monday, August 27, 2012 12:38 PM

Answers

  • There are several errors here. I highly recommend reading Asynchronous programming in C++ to get an idea of how to use asynchronous functions in C++.

    The source of the error message problem is that subfolder is not in scope within the lambda. It is defined as a local to the function and will go out of scope before it can be used within the lambda. You would need to capture it by including it in the lambda's initial [] section in order to use it.

    The bigger set of errors if that you have a lot of calls to async functions which you don't actually trigger and call. For example, the line

    auto subfolder= folder->GetFolderAsync(foldername);
    

    does not set subfolder to the folder; it sets subfolder to an IAsyncOperation which will return the StorageFolder^ when it completes. You'll want something like the following to wrap your IAsyncOperations in tasks and run them serially (untested, since you didn't provide a concrete enough snippet for me to compile):

    	String^ foldername="MYFolder";
    	StorageFolder^ folder=KnownFolders::PicturesLibrary;
    	
    	create_task(folder->CreateFolderAsync(foldername)).then([this, source, destination](StorageFolder^ subfolder)
    	{
    		create_task(KnownFolders::PicturesLibrary->CreateFileAsync(destination, CreationCollisionOption::GenerateUniqueName)).then([this, source, subfolder] (StorageFile^ destinationFile)
    		{
    			BackgroundDownloader^ downloader = ref new BackgroundDownloader();
    			DownloadOperation^ download = downloader->CreateDownload(source, destinationFile);
    
    			//Log("Downloading " + source->AbsoluteUri + " to " + destinationFile->Name + ", " + download->Guid);
    			create_task(destinationFile->MoveAsync(subfolder)).then([this,download](void)
    			{
    		
    				// Attach progress and completion handlers.
    				HandleDownloadAsync(download, true);
    			});
    		});
    	});

    --Rob

    Tuesday, August 28, 2012 10:10 PM
    Owner

All replies

  • What does your code look like? The error sounds like you have the lambda set up incorrectly: are you using a local variable without capturing it?

    If you are capturing the variable but still get this error then when do you get the error? Is it an Intellisense problem? Does the code compile and run fine or do you get an error or warning on compile?

    --Rob

    Monday, August 27, 2012 3:44 PM
    Owner
  • String^ foldername="MYFolder";
    StorageFolder^ folder=KnownFolders::PicturesLibrary;
    	folder->CreateFolderAsync(foldername);
    	auto subfolder= folder->GetFolderAsync(foldername);
    	//folder->GetFolderFromPathAsync(foldername)->createFileAsync("file.txt");
    	task<StorageFile^>(KnownFolders::PicturesLibrary->CreateFileAsync(destination, CreationCollisionOption::GenerateUniqueName)).then([this, source] (StorageFile^ destinationFile)
    	{
    		BackgroundDownloader^ downloader = ref new BackgroundDownloader();
    		DownloadOperation^ download = downloader->CreateDownload(source, destinationFile);
    
    		Log("Downloading " + source->AbsoluteUri + " to " + destinationFile->Name + ", " + download->Guid);
    		destinationFile->MoveAsync(subfolder);
    		
    		// Attach progress and completion handlers.
    		HandleDownloadAsync(download, true);
    	}

    When I was trying to move it into subfolder in the code am getting the error.

    Please let me know how to use it.

    Tuesday, August 28, 2012 4:16 AM
  • Am developing an application using C++ xaml.

    Am trying to save a file in a folder which is in DocumentsLibrary. Can anyone help me in this scenario.

    When am trying to do this am getting an error:

    "an enclosing-functional local variable cannot be referenced in a lambda body unless it is in  the capture list."

    Can any one help me in this scenario.

    Go into app manifest and set to allow to write to documents folder then in the next tab set the file extensions you choose to use.


    n.Wright


    Tuesday, August 28, 2012 9:00 PM
  • There are several errors here. I highly recommend reading Asynchronous programming in C++ to get an idea of how to use asynchronous functions in C++.

    The source of the error message problem is that subfolder is not in scope within the lambda. It is defined as a local to the function and will go out of scope before it can be used within the lambda. You would need to capture it by including it in the lambda's initial [] section in order to use it.

    The bigger set of errors if that you have a lot of calls to async functions which you don't actually trigger and call. For example, the line

    auto subfolder= folder->GetFolderAsync(foldername);
    

    does not set subfolder to the folder; it sets subfolder to an IAsyncOperation which will return the StorageFolder^ when it completes. You'll want something like the following to wrap your IAsyncOperations in tasks and run them serially (untested, since you didn't provide a concrete enough snippet for me to compile):

    	String^ foldername="MYFolder";
    	StorageFolder^ folder=KnownFolders::PicturesLibrary;
    	
    	create_task(folder->CreateFolderAsync(foldername)).then([this, source, destination](StorageFolder^ subfolder)
    	{
    		create_task(KnownFolders::PicturesLibrary->CreateFileAsync(destination, CreationCollisionOption::GenerateUniqueName)).then([this, source, subfolder] (StorageFile^ destinationFile)
    		{
    			BackgroundDownloader^ downloader = ref new BackgroundDownloader();
    			DownloadOperation^ download = downloader->CreateDownload(source, destinationFile);
    
    			//Log("Downloading " + source->AbsoluteUri + " to " + destinationFile->Name + ", " + download->Guid);
    			create_task(destinationFile->MoveAsync(subfolder)).then([this,download](void)
    			{
    		
    				// Attach progress and completion handlers.
    				HandleDownloadAsync(download, true);
    			});
    		});
    	});

    --Rob

    Tuesday, August 28, 2012 10:10 PM
    Owner
  • Hi wrightlyplp,

    While what you suggest is necessary to write to the Documents library, not having the appropriate capabilities and file declarations set would give a different error than what KritiKa described. Also, from the sample snippet he is using the Pictures Library not the Documents Library, so specific file declarations aren't necessary.

    For more information on Documents Library restrictions see the Special Use capabilities section at App capability declarations .

    --Rob

    Tuesday, August 28, 2012 10:16 PM
    Owner
  • The original post says documents library.


    n.Wright

    Tuesday, August 28, 2012 10:20 PM
  • 			  FileSavePicker^ savePicker = ref new FileSavePicker();
    			  savePicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
    
            auto plainTextExtensions = ref new Platform::Collections::Vector<String^>();
            plainTextExtensions->Append(".pcb");
            savePicker->FileTypeChoices->Insert("PCB files", plainTextExtensions);
            savePicker->SuggestedFileName = previousfname;
    
            create_task(savePicker->PickSaveFileAsync()).then([this](StorageFile^ file)
            {
    	if (file==nullptr)	//quit if nothing selected
    			return;
    
    
    
    
    	auto openOp = file->OpenAsync(FileAccessMode::ReadWrite);
        openOp->Completed = 
          ref new AsyncOperationCompletedHandler <IRandomAccessStream^>
          ([=](IAsyncOperation<IRandomAccessStream^>^ operation, AsyncStatus status)
        {
    		
    
    		auto istream = operation->GetResults();
          auto dr = ref new DataWriter(istream);
          
    			int wurd;	
    	            
    			int cx,dx;
               
    			
                ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
                //{SAVE SYMBOLS}
                cx = 1;
                while (symboldata[cx] != 65535)
                    cx = fulldioversymbol(cx);
    
                cx++;
    
                //{symbol save cx words}
                wurd = cx & 0xffff;	//{save length}
                dr->WriteUInt16(rev(wurd));
                wurd = (cx / 65536) & 0xffff;
                dr->WriteUInt16(rev(wurd));
    
                for (dx = 1; dx <= cx; dx++)
                {
                    wurd = symboldata[dx];
                    dr->WriteUInt16(rev(wurd));
                }
    
    
    
    			///////////////////////////////////////////
    			 create_task(dr->StoreAsync()).then([this,dr](UINT16 bytesWritten)
                    {
    					
    
    			 });
    
    			 
    
    	
    	});
    
    
    		});
    
    
    
    
    

    This works ok for me.

    n.Wright

    Tuesday, August 28, 2012 10:26 PM