lajawi
lajawi

Reputation: 99

WinUI 3: WinRT.Interop.WindowNative.GetWindowHandle(this) crashes application

I have a button in my Xaml code like this:

<Button x:Name="PickFolderButton" Click="PickFolderButton_Click"/>

and the code behind is this:

    private async void PickFolderButton_Click(object sender, RoutedEventArgs e)
    {
        BackupDestinationText.Text = "";

        FolderPicker openPicker = new FolderPicker();

        var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

        WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);

        openPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
        openPicker.FileTypeFilter.Add("*");

        StorageFolder folder = await openPicker.PickSingleFolderAsync();
        if (folder != null)
        {
            StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
            BackupDestinationText.Text = folder.Path;
        }
        else
        {
            BackupDestinationText.Text = "Operation cancelled";
        }
    }

Yet, if I run this code (press the button), then I get a general break, it points to the file App.g.i.cs, line 68, global::System.Diagnostics.Debugger.Break();, which is not helpful at all (see image for an inline image).

After @Simon Mourier's suggestion, I tried using the debugger to get more info on the error, with it, I got this error in the DispatcherQueueSynchronizationContext.cs file, which is read only:

System.InvalidCastException
  HResult=0x80004002
  Message=Specified cast is not valid.
  Source=WinRT.Runtime
  StackTrace:
   at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object obj, Guid iid) in WinRT\ComWrappersSupport.cs:line 888
   at WinRT.MarshalInspectable`1.CreateMarshaler2(T o, Guid iid, Boolean unwrapObject) in WinRT\MarshalInspectable.cs:line 53
   at WinRT.Interop.IWindowNativeMethods.get_WindowHandle(Object _obj) in WinRT.Interop\IWindowNativeMethods.cs:line 11
   at WinRT.Interop.WindowNative.GetWindowHandle(Object target) in WinRT.Interop\WindowNative.cs:line 9
   at BackupTool.Views.NewProfilePage.<PickFolderButton_Click>d__10.MoveNext() in C:\Users\user\source\repos-private\BackupTool\Views\NewProfilePage.xaml.cs:line 126
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state) in System.Threading.Tasks\Task.cs:line 1851
   at Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.<>c__DisplayClass2_0.<Post>b__0() in Microsoft.UI.Dispatching\DispatcherQueueSynchronizationContext.cs:line 29

  This exception was originally thrown at this call stack:
    WinRT.ComWrappersSupport.CreateCCWForObjectForABI(object, System.Guid) in ComWrappersSupport.cs
    WinRT.MarshalInspectable<T>.CreateMarshaler2(T, System.Guid, bool) in MarshalInspectable.cs
    WinRT.Interop.IWindowNativeMethods.get_WindowHandle(object) in IWindowNativeMethods.cs
    WinRT.Interop.WindowNative.GetWindowHandle(object) in WindowNative.cs
    BackupTool.Views.NewProfilePage.PickFolderButton_Click(object, Microsoft.UI.Xaml.RoutedEventArgs) in NewProfilePage.xaml.cs
    System.Threading.Tasks.Task.ThrowAsync.AnonymousMethod__128_0(object) in Task.cs
    Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.Post.AnonymousMethod__0() in DispatcherQueueSynchronizationContext.cs```


After some trial and error, it seems that following line in by button code is the culprit:
```cs
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

It seems like the same issue as this post, on which the working answer was this from @mm8. It goes as follows:

Change the modifier for the m_window field in App.xaml.cs:

internal Window m_window;

...or better yet expose it through a property:

public Window Window => m_window;

Then you can access the window from the page like this:

var window = (Application.Current as App)?.m_window as MainWindow; 

or

var window = (Application.Current as App)?.Window as MainWindow; 

I've tried adding both proposed solutions to my App.xaml.cs file, of which only the first one did not get an error (second one said: CS0103 The name 'm_window' does not exist in the current context), yet it didn't work (probably because m_Window was never in App.xaml.cs to begin with).

How can I use var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);?

Upvotes: 0

Views: 41

Answers (0)

Related Questions