0

我正在尝试使用我的 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;
}

好吧,既然我不知道为什么,这就是为什么我来这里请求你的帮助。

非常感谢你!

4

1 回答 1

1

UWP 应用程序无法直接访问文件选择器选择的位置。这FileOpenPicker是一个代表您执行此操作的代理,但您不能使用标准文件 I/O,只能使用 WinRT API。请记住,选择的文件甚至可能不在本地文件系统上。您可以直接 I/O 访问的唯一文件位置是已安装文件夹(只读)、临时文件夹(读写)和应用程序数据文件夹(读写)。

有关详细信息,请参阅MSDN 上的文件访问和权限(Windows 运行时应用程序)

一种解决方案是将选定的代理文件复制到您有权访问的临时文件位置,然后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对此进行了详细介绍,其中也包含了编写案例。

于 2016-03-24T05:14:41.673 回答