CsWinRT
CsWinRT copied to clipboard
IL2026 trim warnings on WinRT.TypeExtensions.GetAuthoringMetadataType(Type) for publish builds
Describe the bug
Using WinAppSDK 1.3 stable and projection assemblies using CsWinRT 2.0.2, publishing a trimmed apps results in this warning:
"C:...\Test.csproj" (restore;publish target) (1) -> (_RunILLink target) -> ILLink : Trim analysis warning IL2026: WinRT.TypeExtensions.GetAuthoringMetadataType(Type): Using member 'WinRT.TypeE xtensions.<>c.<GetAuthoringMetadataType>b__14_0(Type)' which has 'RequiresUnreferencedCodeAttribute' can break function ality when trimming application code. If authoring a WinRT component in C# using C#/WinRT authoring support, it might r equire ABI helper types that might get trimmed. Avoid marking such components trimmable or ensure types don't get trimm ed from it. [C:\Users\sergiopedri\source\repos\Win2DRenderer2\Win2DRenderer.csproj] C:\Users\sergiopedri.nuget\packages\microsoft.windows.sdk.net.ref\10.0.22621.28\lib\net6.0\WinRT.Runtime.dll : warni ng IL2104: Assembly 'WinRT.Runtime' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libra ries [C:...\Test.csproj]
To Reproduce
- Create a new project with TFM
net7.0-windows10.0.22621 - Paste the following code:
using System;
using System.Runtime.InteropServices;
using WinRT;
using WinRT.Interop;
_ = MarshalInspectable<IDummy>.FromManaged(null!);
[Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
[WindowsRuntimeType]
[WindowsRuntimeHelperType(typeof(IDummy))]
public interface IDummy
{
[Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
public readonly struct Vftbl
{
public static readonly IntPtr AbiToProjectionVftablePtr = IUnknownVftbl.AbiToProjectionVftblPtr;
}
}
- Publish with this command from a VS Developer Terminal:
msbuild Win2DRenderer.csproj -t:restore,publish /p:Configuration=Release /p:Platform=x64 /p:PublishSingleFile=True /p:SelfContained=True /p:PublishTrimmed=True /p:RuntimeIdentifier=win10-x64
Expected behavior Should build with no warnings.
This is breaking my Win2D sample for ComputeSharp with trimming enabled. I mean in general I'd assume it'd break any use of ComputeSharp with trimming enabled I guess (since they'd all use the same WinRT components), which isn't... Great 🥲
Repro steps
- Clone https://github.com/Sergio0694/ComputeSharp
- Writing this issue as of 63611a4b7011ae5b3703b371c57e9f7d90a39e4d
- Build with a VS 2022 Developer PowerShell, or normal PowerShell provided you have MSBuild in your path:
msbuild samples\ComputeSharp.SwapChain.D2D1.Cli\ComputeSharp.SwapChain.D2D1.Cli.csproj -t:restore,publish /p:Configuration=Release /p:Platform=x64 /p:RuntimeIdentifier=win10-x64 /p:PublishSingleFile=True /p:SelfContained=True /p:PublishTrimmed=True
- Run/debug the .exe at
\samples\ComputeSharp.SwapChain.D2D1.Cli\bin\x64\Release\net7.0-windows10.0.22621\win10-x64\publish\computesharp.d2d1.cli.exe
Result
Crashes with an InvalidCastException:
WinRT.Runtime!WinRT.ExceptionHelpers.ThrowExceptionForHR.__Throw|20_0(int value)
WinRT.Runtime!WinRT.ExceptionHelpers.ThrowExceptionForHR(int value)
Microsoft.Graphics.Canvas.Interop!ABI.Microsoft.Graphics.Canvas.ICanvasDrawingSessionMethods.DrawImage(WinRT.IObjectReference value, Microsoft.Graphics.Canvas.ICanvasImage value)
Microsoft.Graphics.Canvas.Interop!Microsoft.Graphics.Canvas.CanvasDrawingSession.DrawImage(Microsoft.Graphics.Canvas.ICanvasImage value)
computesharp.d2d1.cli!Program.<Main>$.AnonymousMethod__10(object value, ComputeSharp.SwapChain.D2D1.Backend.Win32Application.DrawEventArgs value)
computesharp.d2d1.cli!ComputeSharp.SwapChain.D2D1.Backend.Win32Application.OnUpdate(System.TimeSpan value)
computesharp.d2d1.cli!ComputeSharp.SwapChain.D2D1.Backend.Win32ApplicationRunner.Run.AnonymousMethod__5_0(object value)
System.Private.CoreLib!System.Threading.Thread.StartHelper.RunWorker()
System.Private.CoreLib!System.Threading.Thread.StartHelper.Run()
System.Private.CoreLib!System.Threading.Thread.StartCallback()
@manodasanW is this something that can be fixed, and/or is there a workaround for the short term? 😅
Update: I could work around this by adding these directives to my type's constructor:
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasImageInterop.Interface))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasImageInterop.Interface.Vftbl))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasFactoryNative.Interface))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasFactoryNative.Interface.Vftbl))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasEffectFactoryNative.Interface))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasEffectFactoryNative.Interface.Vftbl))]
This did solve the issue. But it's not really ideal, it seems custom components are just broken by default 🥲