none
C++ UWP FileSavePicker does not write data to file

    Вопрос

  • I have a dll, that allows me to call UWP FileSavePicker from another app(unity3d one). It works ok, opens a picker, creates an empty file with the name we have set for that.

    But, when I try to write into that file BYTE[], it doesnt drop any exceptions, all goes well, but file still empty.

    I have ensured that byte[] exists and doesnt empty.

    What Im doing wrong?

    Here is my source code:

    /*THIS ONE WORKS OK!*/
    extern "C" int __stdcall ShowFileSavePickerUsingCallback(const wchar_t* suggestedFileName, BYTE* data, CallbackFunc callback)
    {
    
    ComPtr<IInspectable> basePicker;
    auto hr = RoActivateInstance(HStringReference(RuntimeClass_Windows_Storage_Pickers_FileSavePicker).Get(), &basePicker);
    AssertAndReturnIfFailed(hr);
    
    ComPtr<IFileSavePicker> picker;
    hr = basePicker.As(&picker);
    AssertAndReturnIfFailed(hr);
    
    hr = picker->put_SuggestedStartLocation(PickerLocationId::PickerLocationId_DocumentsLibrary);
    AssertAndReturnIfFailed(hr);
    
    hr = picker->put_SuggestedFileName(HStringReference(suggestedFileName).Get());
    AssertAndReturnIfFailed(hr);
    
    
    
    ComPtr<IMap<HSTRING, IVector<HSTRING>*>> fileTypeChoices;
     hr = picker->get_FileTypeChoices(&fileTypeChoices);
     AssertAndReturnIfFailed(hr);
    
     auto txtChoice = Make<StringVector>();
     hr = txtChoice->Append(HStringReference(L".png").Get());
     AssertAndReturnIfFailed(hr);
    
     boolean replaced;
     hr = fileTypeChoices->Insert(HStringReference(L"PNG file").Get(), txtChoice.Get(), &replaced);
     AssertAndReturnIfFailed(hr);
    
     ComPtr<IAsyncOperation<StorageFile*>> op;
     hr = picker->PickSaveFileAsync(&op);
     AssertAndReturnIfFailed(hr);
    
     hr = op->put_Completed(Callback<IAsyncOperationCompletedHandler<StorageFile*>>([callback, data](IAsyncOperation<StorageFile*>* operation, AsyncStatus status) -> HRESULT
     {
      if (status != AsyncStatus::Completed)
      {
       // Figure out the error
    
       ComPtr<IAsyncInfo> asyncInfo;
       auto hr = operation->QueryInterface(IID_PPV_ARGS(&asyncInfo));
       AssertAndReturnIfFailed(hr);
    
       HRESULT errorCode;
       hr = asyncInfo->get_ErrorCode(&errorCode);
       AssertAndReturnIfFailed(hr);
    
       // Do something with errorCode
       // ...
       // ...
    
       return S_OK;
      }
    
      ComPtr<IStorageFile> storageFile;
      auto hr = operation->GetResults(&storageFile);
      AssertAndReturnIfFailed(hr);
    
      ComPtr<IStorageItem> item;
      auto hrr = storageFile->QueryInterface(IID_PPV_ARGS(&item));
      AssertAndReturnIfFailed(hrr);
    
      HString path;
      hr = item->get_Path(path.GetAddressOf());
      AssertAndReturnIfFailed(hr);
    
      uint32_t pathLen;
      const wchar_t *pathStr = path.GetRawBuffer(&pathLen);
    
      SaveDataToAStream(data, storageFile.Get(), callback);
    
      return S_OK;
     }).Get());
     AssertAndReturnIfFailed(hr);
    
     return S_OK;
    }
    
    /*THIS ONE RUNS ALL OK, WITHOUT ERRORS, BUT FILE IS EMPTY((*/
    int SaveDataToAStream(BYTE* data, IStorageFile*  filePtr, CallbackFunc callback)
    {
     __FIAsyncOperation_1_Windows__CStorage__CStreams__CIRandomAccessStream_t * operation;
     __debugbreak();
     auto hr = filePtr->OpenAsync(FileAccessMode::FileAccessMode_ReadWrite, &operation);
     AssertAndReturnIfFailed(hr);
    
     Event operationCompleted(CreateEvent(nullptr, true, false, nullptr));
    
     hr = operation->put_Completed(Callback<IAsyncOperationCompletedHandler<IRandomAccessStream*>>
      ([&](IAsyncOperation<IRandomAccessStream*> *pHandler, AsyncStatus status) -> HRESULT
     {
      SetEvent(operationCompleted.Get());
      return S_OK;
     }).Get());
    
     AssertAndReturnIfFailed(hr);
    
    
     WaitForSingleObject(operationCompleted.Get(), INFINITE);
    
     ComPtr<IRandomAccessStream> stream;
    
     hr = operation->GetResults(&stream);
     AssertAndReturnIfFailed(hr);
    
     IOutputStream * outputStream;
    
     hr = stream->GetOutputStreamAt(0, &outputStream);
     AssertAndReturnIfFailed(hr);
    
     ComPtr<IDataWriter> dataWriter;
    
     ComPtr<IDataWriterFactory> dataWriterFactory;
    
     Windows::Foundation::GetActivationFactory
     (HStringReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(), &dataWriterFactory);
    
     hr = dataWriterFactory->CreateDataWriter(outputStream, &dataWriter);
     AssertAndReturnIfFailed(hr);
    
     UINT32 byteCount;
    
     hr = dataWriter->WriteBytes(sizeof(data), data);
     AssertAndReturnIfFailed(hr);
    
     __FIAsyncOperation_1_UINT32_t * storeOperation;
    
     Event storeOperationCompleted(CreateEvent(nullptr, true, false, nullptr));
    
     hr = dataWriter->StoreAsync(&storeOperation);
     AssertAndReturnIfFailed(hr);
    
    
     __debugbreak();
     hr = storeOperation->put_Completed(Callback<IAsyncOperationCompletedHandler<UINT32>>
      ([&](IAsyncOperation<UINT32> *pHandler, AsyncStatus status) -> HRESULT
     {
      SetEvent(storeOperationCompleted.Get());
    
    
      ComPtr<IStorageItem> item;
      auto hrr = filePtr->QueryInterface(IID_PPV_ARGS(&item));
      AssertAndReturnIfFailed(hrr);
    
      HString path;
      HRESULT hr = item->get_Path(path.GetAddressOf());
      AssertAndReturnIfFailed(hr);
    
      uint32_t pathLen;
      const wchar_t *pathStr = path.GetRawBuffer(&pathLen);
      __debugbreak();
      callback(pathStr);
    
      return S_OK;
     }).Get());
     AssertAndReturnIfFailed(hr);
    
     WaitForSingleObject(storeOperationCompleted.Get(), INFINITE);
    
     return 0;
    }
    
    
    

    17 февраля 2017 г. 12:03

Все ответы

  • Hi Polosatiy,

    thanks for posting here.

    Since your case is more related to UWP, I will move it to UWP forum for better support.

    Your understanding and cooperation will be grateful.

    Best Regards,
    Sera Yu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    15 ч. 42 мин. назад
  • I think that the first argument of ‘WriteBytes(sizeof(data), data)’ is not correct since data is a pointer and sizeof gives the size of the pointer instead of the array length. You should introduce a new parameter containing the length. Also make sure that the line is achieved and executed.

    13 ч. 16 мин. назад