You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI 3中C++调用FileOpenPicker出现内存错误求助

WinUI3 C++ 打开文件选择器抛出hresult_error的解决方法

问题分析

你当前用GetProcessFirstWindowHandle()获取HWND的方式不可靠,这个方法拿到的不一定是WinUI3应用的主窗口句柄,导致文件选择器无法正确关联父窗口,最终调用PickSingleFileAsync().get()时抛出异常。

正确解决方案

要获取当前WinUI3页面所在窗口的真实HWND,步骤如下:

  1. 从页面的XamlRoot获取关联的Window对象
  2. 通过WindowId获取对应的HWND
  3. 用正确的HWND初始化文件选择器

修改后的Button_Click代码:

#include <winrt/Microsoft.UI.WindowId.h>
#include <winrt/Microsoft.UI.Xaml.h>

void winrt::App1::implementation::Tab1Page::Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
    OutputTextBlock().Text(OutputTextBlock().Text() + L"Button Clicked\n");

    // 获取当前页面所在的Window
    auto window = this->XamlRoot().Content().as<winrt::Microsoft::UI::Xaml::Window>();
    // 获取Window对应的HWND
    auto windowId = winrt::Microsoft::UI::WindowId::GetForWindow(window);
    auto hwnd = windowId.TryGetWindowHandle();

    if (hwnd)
    {
        auto picker = winrt::Windows::Storage::Pickers::FileOpenPicker();
        // 初始化文件选择器的父窗口句柄
        auto initializeWithWindow = picker.as<::IInitializeWithWindow>();
        initializeWithWindow->Initialize(hwnd.value());
        
        picker.SuggestedStartLocation(winrt::Windows::Storage::Pickers::PickerLocationId::Desktop);
        winrt::Windows::Storage::StorageFile file = picker.PickSingleFileAsync().get();
        
        if (file)
        {
            OutputTextBlock().Text(OutputTextBlock().Text() + L"Selected file: " + file.Name() + L"\n");
        }
    }
    else
    {
        OutputTextBlock().Text(OutputTextBlock().Text() + L"Failed to get window handle\n");
    }
}

额外优化建议

建议使用co_await替代.get()调用异步方法,避免阻塞UI线程,提升应用响应性:

// 修改函数为异步类型
winrt::fire_and_forget winrt::App1::implementation::Tab1Page::Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
    // ... 前面HWND获取代码不变
    
    if (hwnd)
    {
        // ... picker初始化代码不变
        
        winrt::Windows::Storage::StorageFile file = co_await picker.PickSingleFileAsync();
        
        if (file)
        {
            OutputTextBlock().Text(OutputTextBlock().Text() + L"Selected file: " + file.Name() + L"\n");
        }
    }
}

内容的提问来源于stack exchange,提问作者Gaurang Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:40:19