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 可以处理“找不到文件”。不确定为什么默认设置是触发异常。