У меня есть DLL, которая позволяет мне вызывать UWP FileSavePicker из другого приложения (unity3d one). Он работает нормально, открывает средство выбора, создает пустой файл с именем, которое мы установили для этого.
Но когда я пытаюсь записать в этот файл BYTE [], он не отбрасывает никаких исключений, все идет хорошо, но файл все еще пустой.
Я гарантировал, что byte [] существует и не очищается.
Что я делаю не так?
Вот мой исходный код:
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;
}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;
}
Задача ещё не решена.
Других решений пока нет …