WindowsAppSDK: Preview 4 - FolderPicker and FilePicker not working / App crashes

Simple to reproduce:

I have downloaded VisualStudio 2019 Preview Version 16.9 and installed with WinUI 3 preview 4.

I have created a new WinUI Desktop App with .Net 5. In the method myButton_Click i have this code:

string Filename = "";
var picker = new Windows.Storage.Pickers.FileOpenPicker();
((IInitializeWithWindow)(object)picker).Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();

and the interface in the same namespace:

[ComImport]
        [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IInitializeWithWindow
        {
            void Initialize(IntPtr hwnd);
        }

I build my app, the app starts without errors. After i click on the button, the app crashs with this message: Ausnahmefehler bei 0x76E36D21 (combase.dll) in App1.exe: 0xC000027B: Anwendungsinterne Ausnahme (Parameter: 0x1BD90608, 0x00000001)

Without the interface i receive the message “Invalid Window handle”. The same behavior is with the FolderPicker.

Windows app type:

UWP Win32
No Yes
Windows 10 version Saw the problem?
Insider Build (xxxxx)
October 2020 Update (19042) Yes
May 2020 Update (19041)
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop Yes
Xbox
Surface Hub
IoT

This is my first bug report an i hope this is correct. Best regards Andy

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 25 (3 by maintainers)

Most upvoted comments

I have just tested the small code below, and it works for me.

private async void MyButton_Click(object sender, RoutedEventArgs e)
{
  var filePicker = new FileOpenPicker();

  // Pass in the current WinUI window and get its handle
  var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);     
  WinRT.Interop.InitializeWithWindow.Initialize(filePicker, hwnd);

  filePicker.FileTypeFilter.Add("*");

   // Now you can call methods on filePicker
  var file = await filePicker.PickSingleFileAsync();
}

Without writing Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")

Wiki Call WinRT COM interop interfaces from .NET 5+ apps

I’m facing something similar and none of the solutions seem to be working for me. I’m building a WinUI 3 Desktop app on Windows 11 and in VS2019.

Code:

// Open a text file.
FileOpenPicker open = new();
open.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
open.FileTypeFilter.Add("*");

// When running on win32, FileOpenPicker needs to know the top-level hwnd via IInitializeWithWindow::Initialize.
if (Window.Current == null)
{
    IntPtr hwnd = GetActiveWindow();
    IInitializeWithWindow initializeWithWindowWrapper = FileOpenPicker.As<IInitializeWithWindow>();
    initializeWithWindowWrapper.Initialize(hwnd);
}

var files = await open.PickMultipleFilesAsync();

Exception: Specified cast is not valid.

Screenshot: image

@Aloento can you explain what’s not working? Can you share your full code sample? What exception is being thrown and at what line? Make sure you’re calling this.As<IWindowNative>().WindowHandle; from a foreground UI thread from directly within a Window class (or pass your window instead of the this parameter`, you need to obtain the window handle from a Window class

There is an unhandled exception at 0x76556AB1 (combase.dll) (in Reunion.exe): 0xC000027B: An internal application exception has occurred. (Parameter: 0x1D07C6E0, 0x00000001).

using System;
using System.Runtime.InteropServices;
using Microsoft.UI.Xaml;
using Windows.Storage.Pickers;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Reunion
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void MyButton_Click(object sender, RoutedEventArgs e)
        {
            var filePicker = new FileOpenPicker();

            //Get the Window's HWND
            var hwnd = As<IWindowNative>().WindowHandle;

            //Make folder Picker work in Win32

            var initializeWithWindow = FileOpenPicker.As<IInitializeWithWindow>();
            initializeWithWindow.Initialize(hwnd);
            filePicker.FileTypeFilter.Add("*");

            var folder = await filePicker.PickSingleFileAsync();
        }

        [ComImport]
        [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IInitializeWithWindow
        {
            void Initialize(IntPtr hwnd);
        }
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("EECDBF0E-BAE9-4CB6-A68E-9598E1CB57BB")]
        internal interface IWindowNative
        {
            IntPtr WindowHandle { get; }
        }
    }
}

I know where is the problem. I should use using WinRT; It works fine.

Thanks for linking this issue @eleanorleffler. It seems that PickMultipleFilesAsync fails for other reasons. Let’s take care of this in the microsoft/microsoft-ui-xaml#4198 issue. Is that ok with you?

@AndyMahub The need of initializeWithWindow is a common pattern in WinRT APIs that require to specify a window that hosts the UI. It was designed in this way. The Project Reunion team is working on improving the Pickers story, but I don’t know yet whether they will simplify this. Meanwhile, we will need to live with it. Adding @ptorr-msft and for awareness,

@orapps44

I’ve tried all your proposal, unfortunnately none of them works on my side (WUINUI3 + .net 6.0).

I’m pretty disapointed to see even basics aren’t fully supported yet…

private async void LoadFromFile(object sender, RoutedEventArgs e)
{
    var fPicker = new FileOpenPicker();

    var handle = WinRT.Interop.WindowNative.GetWindowHandle(ABootstrap.Resolve<MainWindow>());
    WinRT.Interop.InitializeWithWindow.Initialize(fPicker, handle);

    fPicker.FileTypeFilter.Add("*");

    var selected = await fPicker.PickSingleFileAsync();
}

Replace ABootstrap.Resolve<MainWindow>() with a reference to your MainWindow, in my case I use dependency injection to aquire it from everywhere… you can just make a static reference if you like

I have just tested the small code below, and it works for me.

private async void MyButton_Click(object sender, RoutedEventArgs e)
{
  var filePicker = new FileOpenPicker();

  // Pass in the current WinUI window and get its handle
  var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);     
  WinRT.Interop.InitializeWithWindow.Initialize(filePicker, hwnd);

  filePicker.FileTypeFilter.Add("*");

   // Now you can call methods on filePicker
  var file = await filePicker.PickSingleFileAsync();
}

Without writing Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")

Wiki Call WinRT COM interop interfaces from .NET 5+ apps

Using WinUI3, you’d better do like this: WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);

It appears the same work around is now required for MessageDialog. I’m still not sure I understand why this is “by-design” and if it is, I’m not sure I agree with the design. @andrewleader is there any way we can track an on-going issue to tidy this up in the long term? Surely there must be a more intuitive way so that we don’t end up with code being littered with As<IInitializeWithWindow>() calls.

@Aloento can you explain what’s not working? Can you share your full code sample? What exception is being thrown and at what line?

Make sure you’re calling this.As<IWindowNative>().WindowHandle; from a foreground UI thread from directly within a Window class (or pass your window instead of the this parameter`, you need to obtain the window handle from a Window class

@AndyMahub,

I have just tested the code below with Preview 4 bits, and it works for me.


 public sealed partial class MainWindow : Window
 {
      ...

        private async void myButton_Click(object sender, RoutedEventArgs e)
        {
            var filePicker = new FileOpenPicker();

            //Get the Window's HWND
            var hwnd = this.As<IWindowNative>().WindowHandle;

            //Make folder Picker work in Win32

            var initializeWithWindow = filePicker.As<IInitializeWithWindow>();
            initializeWithWindow.Initialize(hwnd);
            filePicker.FileTypeFilter.Add("*");

            var folder = await filePicker.PickSingleFileAsync();
            myText.Text = folder != null ? folder.Path : string.Empty;
        }

        [ComImport]
        [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IInitializeWithWindow
        {
            void Initialize(IntPtr hwnd);
        }
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("EECDBF0E-BAE9-4CB6-A68E-9598E1CB57BB")]
        internal interface IWindowNative
        {
            IntPtr WindowHandle { get; }
        }
...
}