C++/WinRT 处理来自 StorageFolder::GetFileAsync 的异常
C++/WinRT handling exceptions from StorageFolder::GetFileAsync
当不存在文件时,应用会抛出一个我无法捕获的异常
在我下面的示例代码中,我创建了一个目录“MyFolder”并保存了一个文件“”,并向其中保存了一个文件“sample.txt”。
然后我两次调用函数 FindFileAsync - 首先使用已经创建的文件“sample.txt”,它工作正常,然后使用一个不存在的文件“nofile.txt”,它失败并出现错误
在 FindFile.exe 中的 0x00007FF94E39D759 抛出异常:Microsoft C++ 异常:winrt::hresult_error 在内存位置。
这个问题有什么解决办法吗
MainPage.h
#pragma once
#include "MainPage.g.h"
namespace winrt::FindFile::implementation
{
struct MainPage : MainPageT<MainPage>
{
MainPage();
Windows::Foundation::IAsyncAction FindFileAsync(hstring value);
Windows::Foundation::IAsyncAction GetFolderAsync(hstring const& value);
Windows::Foundation::IAsyncAction CreateFileAsync(hstring const& fname);
Windows::Foundation::IAsyncAction DeletefileAsync(Windows::Storage::StorageFile const & value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
private:
hstring folderDir{ L"MyFolder" };
};
}
namespace winrt::FindFile::factory_implementation
{
struct MainPage : MainPageT<MainPage, implementation::MainPage>
{
};
}
MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Popups;
namespace winrt::FindFile::implementation
{
MainPage::MainPage()
{
InitializeComponent();
}
Windows::Foundation::IAsyncAction MainPage::FindFileAsync(hstring value)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
StorageFolder sampleFolder{ co_await storageFolder.CreateFolderAsync(folderDir, CreationCollisionOption::OpenIfExists) };
try
{
Windows::Storage::StorageFile manifest{ co_await sampleFolder.GetFileAsync(value) };
}
catch (winrt::hresult_error msg)
{
hstring ms{ msg.message() };
MessageDialog dlg(ms, L"File Error");
dlg.ShowAsync();
}
}
Windows::Foundation::IAsyncAction MainPage::GetFolderAsync(hstring const& value)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFolder{ co_await storageFolder.CreateFolderAsync(value, CreationCollisionOption::OpenIfExists) };
}
IAsyncAction MainPage::CreateFileAsync(hstring const& fname)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFolder{ co_await storageFolder.CreateFolderAsync(folderDir, CreationCollisionOption::OpenIfExists) };
auto sampleFile{ co_await sampleFolder.CreateFileAsync(L"sample.txt", Windows::Storage::CreationCollisionOption::ReplaceExisting) };
co_await Windows::Storage::FileIO::WriteTextAsync(sampleFile, L"Swift as a shadow");
}
IAsyncAction MainPage::DeletefileAsync(StorageFile const& value)
{
co_await value.DeleteAsync();
}
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
hstring fname{ L"sample.txt" };
GetFolderAsync(folderDir);
CreateFileAsync(fname);
// The following statement is successful as the file exists
FindFileAsync(fname);
// The following ststement throws an exception error
FindFileAsync(L"nofile.txt");
}
}
在 C++/WinRT 中,一些(但不是全部)异常会强制调试器暂停程序执行,尽管正在处理异常(在 try 块内抛出)。但是,您可以通过按 F5 或在没有调试器的情况下启动应用程序(CTRL+F5 或通过开始菜单)来恢复它。我不确定这是错误还是预期行为。
我找到了适合我的解决方案。
当调试器触发异常时,消息包含一个选中的复选框。如果取消选中并且程序继续执行到最后,问题就解决了。当再次 运行 时,不会触发错误并且 catch 可以处理“找不到文件”。不确定为什么默认设置是触发异常。
当不存在文件时,应用会抛出一个我无法捕获的异常 在我下面的示例代码中,我创建了一个目录“MyFolder”并保存了一个文件“”,并向其中保存了一个文件“sample.txt”。 然后我两次调用函数 FindFileAsync - 首先使用已经创建的文件“sample.txt”,它工作正常,然后使用一个不存在的文件“nofile.txt”,它失败并出现错误 在 FindFile.exe 中的 0x00007FF94E39D759 抛出异常:Microsoft C++ 异常:winrt::hresult_error 在内存位置。 这个问题有什么解决办法吗
MainPage.h
#pragma once
#include "MainPage.g.h"
namespace winrt::FindFile::implementation
{
struct MainPage : MainPageT<MainPage>
{
MainPage();
Windows::Foundation::IAsyncAction FindFileAsync(hstring value);
Windows::Foundation::IAsyncAction GetFolderAsync(hstring const& value);
Windows::Foundation::IAsyncAction CreateFileAsync(hstring const& fname);
Windows::Foundation::IAsyncAction DeletefileAsync(Windows::Storage::StorageFile const & value);
void ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
private:
hstring folderDir{ L"MyFolder" };
};
}
namespace winrt::FindFile::factory_implementation
{
struct MainPage : MainPageT<MainPage, implementation::MainPage>
{
};
}
MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Popups;
namespace winrt::FindFile::implementation
{
MainPage::MainPage()
{
InitializeComponent();
}
Windows::Foundation::IAsyncAction MainPage::FindFileAsync(hstring value)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
StorageFolder sampleFolder{ co_await storageFolder.CreateFolderAsync(folderDir, CreationCollisionOption::OpenIfExists) };
try
{
Windows::Storage::StorageFile manifest{ co_await sampleFolder.GetFileAsync(value) };
}
catch (winrt::hresult_error msg)
{
hstring ms{ msg.message() };
MessageDialog dlg(ms, L"File Error");
dlg.ShowAsync();
}
}
Windows::Foundation::IAsyncAction MainPage::GetFolderAsync(hstring const& value)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFolder{ co_await storageFolder.CreateFolderAsync(value, CreationCollisionOption::OpenIfExists) };
}
IAsyncAction MainPage::CreateFileAsync(hstring const& fname)
{
Windows::Storage::StorageFolder storageFolder{ Windows::Storage::ApplicationData::Current().LocalFolder() };
auto sampleFolder{ co_await storageFolder.CreateFolderAsync(folderDir, CreationCollisionOption::OpenIfExists) };
auto sampleFile{ co_await sampleFolder.CreateFileAsync(L"sample.txt", Windows::Storage::CreationCollisionOption::ReplaceExisting) };
co_await Windows::Storage::FileIO::WriteTextAsync(sampleFile, L"Swift as a shadow");
}
IAsyncAction MainPage::DeletefileAsync(StorageFile const& value)
{
co_await value.DeleteAsync();
}
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
hstring fname{ L"sample.txt" };
GetFolderAsync(folderDir);
CreateFileAsync(fname);
// The following statement is successful as the file exists
FindFileAsync(fname);
// The following ststement throws an exception error
FindFileAsync(L"nofile.txt");
}
}
在 C++/WinRT 中,一些(但不是全部)异常会强制调试器暂停程序执行,尽管正在处理异常(在 try 块内抛出)。但是,您可以通过按 F5 或在没有调试器的情况下启动应用程序(CTRL+F5 或通过开始菜单)来恢复它。我不确定这是错误还是预期行为。
我找到了适合我的解决方案。 当调试器触发异常时,消息包含一个选中的复选框。如果取消选中并且程序继续执行到最后,问题就解决了。当再次 运行 时,不会触发错误并且 catch 可以处理“找不到文件”。不确定为什么默认设置是触发异常。