CsWinRT
CsWinRT copied to clipboard
Invalid cast from 'WinRT.IInspectable' to 'System.Collections.Generic.IEnumerable`1[Windows.Storage.IStorageFile]
This issue is a duplication of the https://github.com/microsoft/microsoft-ui-xaml/issues/4111 that @stevenwdv created and it seems a C#/WinRT projection issue.
Casting a collection of StorageFile
s to a collection of IStorageFiles
and using it fails at runtime (this may also be the case with other interfaces, not sure. This only happens when using Desktop WinUI 3.
Steps to reproduce the bug
- Create a new C# "Blank App, Packaged (WinUI in Desktop)"
- Add the following code to e.g.
OnLauched
inApp.xaml.cs
:
Task.Run(async () =>
{
try
{
var folder = ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
_ = ((IReadOnlyList<IStorageFile>) files).ToList();
}
catch (InvalidCastException ex)
{
Debugger.Break();
}
});
- Run the package project (enabling break on CLR exceptions recommended)
- Observe the
InvalidCastException
inDynamicInterfaceCastableHelpers.IsInterfaceImplemented
Expected behavior Should work without exception.
Version Info [Microsoft.WinUI 3.0.0-preview4.210210.4]
Windows app type:
UWP | Win32 |
---|---|
No | Yes |
Windows 10 version | Saw the problem? |
---|---|
Insider Build (20H2: 19042.746) | Yes |
May 2020 Update (19041) | Yes |
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 |
@marb2000 I am following your repro steps, and when I build the packaging project it fails with the error below. Did you experience this?
Error Unable to find WinRT class registrations for WinUI. Please ensure that the Microsoft.WinUI package restored successfully. WinUIApp (Package) C:\gh\Repros\GH_747\WinUIApp\WinUIApp (Package)\build\Microsoft.WinUI.AppX.targets 31
Sorry @j0shuams, I didn't aware you send this to me. I can create a repro for you if needed.
@marb2000 It is okay, I got a repro thanks. I have an idea for a solution but it will require some work. I will update on when I will be focusing on this.
@marb2000 Thanks for your patience on this. I am working on a solution. This has been a difficult one, as WinRT does not support covariance and we are trying to add ad-hoc support for it. Hoping to have a solution in this week.
This looks like it might be fixed by a .NET change: https://github.com/dotnet/runtime/issues/58619
Sounds like the mentioned change is a prerequisite and in addition to that we will need some changes too.
I'm running into a similar issue right now trying to cast from WinRT.IInspectable to Windows.UI.Xaml.DependencyObject. Do you think that is the same root problem?
@scout208 Could be, are you trying to use covariance? I just checked and the issue is still there for the version I'm using (but I'm not using .NET 6 or VS 2022 yet if that matters).
@stevenwdv Thanks for the reply. I am using .NET 6. Actually, I think my issue was more closely related to this one https://github.com/microsoft/CsWinRT/issues/977 and the solution provided there worked for me. I was trying to pass the PrimaryCommands
property of a CommandBar
to a method and when on UWP it would always get passed as a DependencyObject
for some reason on WinUI it gets passed as WinRT.IInspectable.
Not really sure why that is.
Anyways, I just added (IObservableVector<ICommandBarElement>)(object)
before the object in the method I passed it to and I was able to get it to do what I needed to do.
Internal bug: https://microsoft.visualstudio.com/OS/_workitems/edit/37676724
I hit a very similar issue, invalid cast from WinRT.IInspectable, when I was trying to access IReadOnlyList of displayAreas
Steps to repro:
- Create Blank app, Packaged (WinUI3 in Desktop) C#
- During myButton_Click event, call the following apis: IReadOnlyList<Microsoft.UI.WIndowing.DisplayArea> displayAreas = Microsoft.UI.WIndowing.DisplayArea.FindAll(); if(displayAreas != null) { // Now try to access display areas displayAreas.Count or displayAreas[0] int displayAreasCount = displayAreas.Count; // This line throws an invalid cast from WinRT.IInspectable exception }
- When the button is clicked the invalid cast from WinRT.IInspectable exception is raised.