我试图用我的DirectX 11项目打开DDS文件,但是,大多数情况下,它拒绝打开它。每次失败,我都会收到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;
}
好吧,因为我不明白为什么,这就是为什么我来这里请求你的帮助。
非常感谢!
答案 0 :(得分:0)
UWP应用程序没有对文件选择器选择的位置的直接文件访问权限。 FileOpenPicker
是代表您执行此操作的代理,但您不能使用标准文件I / O,只能使用WinRT API。请记住,挑选的文件甚至可能不在本地文件系统上。您可以直接访问I / O的唯一文件位置是已安装的文件夹(只读),临时文件夹(读写)和应用程序数据文件夹(读写)。
有关详细信息,请参阅MSDN上的File access and permissions (Windows Runtime apps)。
解决方案是将选定的代理文件复制到您有权访问的临时文件位置,然后在临时副本上使用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 wiki详细介绍了这一点,写作案例也涵盖了there。