如何从 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();
...
}
}
我正在使用 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();
...
}
}