如何从 Windows::Storage::StorageFile 创建 std::filesystem::exists() 兼容路径?

How do I create a std::filesystem::exists() compatible path from a Windows::Storage::StorageFile?

我正在使用 FileOpenPicker 在 Windows 通用应用程序中获取文件 (StorageFile^)。这似乎工作正常,如果我输出 StorageFile->Path->Data(),它 returns 预期的文件路径 (C:...\MyFile.txt).

当我尝试打开它并将内容转储到字符串时出现问题(字符串什么也没接收),所以作为第一步,我试图用 std::filesystem::exists() 验证文件路径。

要将其剪切到相关位:

void MyClass::MyFunction(StorageFile^ InFile)
{
    std::filesystem::path FilePath = InFile->Path->Data();

    if (std::filesystem::exists(FilePath))
    {
        //Do things
    }
}

当我运行这个时,我得到一个异常:

Exception thrown at 0x7780A842 in MyApp.exe: Microsoft C++ exception: std::filesystem::filesystem_error at memory location 0x039BC480.
Unhandled exception at 0x7AACF2F6 (ucrtbased.dll) in MyApp.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

看来,我试图传递给std::filesystem::exists()的路径是无效的。

任何指出我哪里出错的帮助都将不胜感激!

这个问题最初被标记为 this question 的重复问题,但是该解决方案似乎不起作用,因为它需要 CLI(?),而我 认为 我是使用 WinRT(但是我无法在我的项目或设置中找到除了在包含中提供 winrt 之外的地方)。

关于 Windows 运行时(使用 C++/CX 或 C++/WinRT)中的 StorageFile 要记住的关键事项是 (a) 它不一定是磁盘上的文件,并且 (b ) 即使它是磁盘上的文件,您也不需要直接打开它的权限。

唯一可用于对 UWP FilePicker 提供的 StorageFile 实例执行传统文件 I/O 操作的 'generally safe' 模式是从中创建一个临时目录副本然后解析临时副本:

C++/CX

#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

auto openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail; 
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary; 
openPicker->FileTypeFilter->Append(".dds"); 

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)
            {
                std::filesystem::path FilePath = tempFile->Path->Data();
...
            }
        });
    }
});

C++/WinRT

#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Storage.Pickers.h"

using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Storage::Pickers;

FileOpenPicker openPicker;
openPicker.ViewMode(PickerViewMode::Thumbnail);
openPicker.SuggestedStartLocation(PickerLocationId::PicturesLibrary);
openPicker.FileTypeFilter().Append(L".dds");

auto file = co_await openPicker.PickSingleFileAsync();
if (file)
{
    auto tempFolder = ApplicationData::Current().TemporaryFolder();
    auto tempFile = co_await file.CopyAsync(tempFolder, file.Name(), NameCollisionOption::GenerateUniqueName);
    if (tempFile)
    {
        std::filesystem::path FilePath = tempFile.Path().c_str();
...
    }
}

Microsoft Docs