Я пытаюсь открыть файл DDS с моим проектом DirectX 11, однако в большинстве случаев он отказывается его открывать. Каждый раз, когда это терпит неудачу, я получаю ошибку E_ACCESSDENIED.
Единственный способ заставить его работать — это указать относительный путь к текущему каталогу или подкаталогу. Если это относительный путь к родительскому каталогу или абсолютный путь, функция завершится ошибкой.
Проблема в том, что я хочу открыть изображение с помощью FileOpenPicker, поэтому в каждом случае я получаю абсолютный путь …
Я поделюсь своими функциями:
void Element::FileOpenDialog()
{
FileOpenPicker^ fileOpenPicker = ref new FileOpenPicker();
fileOpenPicker->ViewMode = PickerViewMode::Thumbnail;
fileOpenPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
fileOpenPicker->CommitButtonText = "Load";
fileOpenPicker->FileTypeFilter->Append(".dds");
create_task(fileOpenPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
{
if (file)
{
m_fullPath = const_cast<wchar_t*>(file->Path->Data());
wcout << m_fullPath << endl; // prints the correct path of the selected file
m_loadedImage = false;
}
m_choseImage = true; // Checking in another code if the user chose an image to load.
});
}
И тогда я вызываю функцию для загрузки текстуры …
bool Texture::LoadFile(wchar_t* path, GameWindow^ gameWindow)
{
m_gameWindow = gameWindow;
ComPtr<ID3D11Resource> resource = nullptr;
if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // Works
if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"texture\\texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // Works
if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), L"..\\texture.dds", resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // E_ACCESSDENIED
if (!FH::ThrowIfFailed(CreateDDSTextureFromFile(m_gameWindow->dev.Get(), path, resource.GetAddressOf(), m_texture.ReleaseAndGetAddressOf()))) return false; // E_ACCESSDENIED
return true;
}
Ну, так как я понятия не имею почему, поэтому я прихожу сюда, чтобы попросить вас о помощи.
Большое спасибо!
Приложение UWP не имеет прямого доступа к файлу в месте, выбранном средством выбора файлов. FileOpenPicker
это брокер, который делает это от вашего имени, но вы не можете использовать стандартный файловый ввод-вывод, только WinRT API. Имейте в виду, что выбранный файл может даже не находиться в локальной файловой системе. Единственные местоположения файлов, к которым у вас есть прямой доступ к вводу / выводу, — это установленная папка (только для чтения), временная папка (чтение и запись) и папка данных приложения (чтение и запись).
Увидеть Доступ к файлам и разрешения (приложения Windows Runtime) на MSDN для получения дополнительной информации.
Решение состоит в том, чтобы скопировать выбранный файл брокера во временную папку, к которой у вас есть доступ, и затем использовать CreateDDSTextureFromFile
на временной копии.
#include <ppltasks.h>
using namespace concurrency;
using Windows::Storage;
using Windows::Storage::Pickers;
create_task(openPicker->PickSingleFileAsync()).then([](StorageFile^ file)
{
if (file)
{
auto tempFolder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
create_task(file->CopyAsync(tempFolder, file->Name, NameCollisionOption::GenerateUniqueName)).then([](StorageFile^ tempFile)
{
if (tempFile)
{
HRESULT hr = CreateDDSTextureFromFile(..., tempFile->Path->Data(), ...);
DeleteFile(tempFile->Path->Data());
DX::ThrowIfFailed(hr);
}
});
});
Это подробно описано на DirectX Tool Kit вики, с чехлом записи там также.
Других решений пока нет …