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

.NET 5 TFM环境下调用ICompositorDesktopInterop抛出异常问题咨询

根因分析

.NET 5 及更高版本重构了WinRT类型的互操作机制,移除了对自定义[ComImport]标记的InterfaceIsIInspectable类型的手动封送支持,你遇到的异常就是这个改动导致的。

在.NET Framework 4.8 中,Microsoft.Windows.SDK.Contracts包自带了完整的WinRT类型投影,支持你自定义的IInspectable接口封送逻辑。但.NET 5改用Target Framework Monikers (TFMs) 内置WinRT支持后,这套自定义封送逻辑被废弃,只有SDK自带的投影类型才能被正常封送。

缺失的适配操作

你需要做以下调整解决问题:

  1. 修正项目TFM配置
    首先修改项目文件的目标框架配置,使用带Windows版本后缀的TFM,开启内置WinRT支持,同时指定具体平台架构(WinRT API不支持AnyCPU),示例配置如下:
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <!-- 可根据你需要兼容的最低Windows版本调整版本号,最低不低于10.0.17134.0 -->
        <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
        <UseWinRT>true</UseWinRT>
        <Platforms>x64;x86</Platforms>
      </PropertyGroup>
    </Project>
    
  2. 清理冲突依赖和冗余代码
    • 卸载项目中所有Microsoft.Windows.SDK.Contracts相关的NuGet包,避免和内置WinRT支持产生类型冲突
    • 删除你手动定义的ICompositorDesktopInterop、ICompositionTarget两个[ComImport]接口代码,TFM内置的Windows SDK投影已经包含对应的类型定义,不需要手动声明
  3. 调整互操作代码
    原来Microsoft.Windows.SDK.Contracts包提供的As<T>扩展方法不再可用,改用WinRT内置的封送方法获取互操作接口,修改后的代码如下:
    private ICompositionTarget compositionTarget;
    public Compositor compositor;
    
    private void InitComposition(IntPtr hwnd) 
    {
      compositor = new Compositor();
      // 用内置方法获取桌面互操作接口
      var interop = WinRT.MarshalInspectable.As<Compositor, ICompositorDesktopInterop>(compositor);
      interop.CreateDesktopWindowTarget(hwnd, true, out compositionTarget);
      compositionTarget.Root = compositor.CreateSpriteVisual();
    }
    

额外注意事项

如果按照以上配置还是报错,可以安装Microsoft.Windows.CsWin32NuGet包,通过该工具自动生成所需的COM接口定义,完全避免手动写ComImport代码可能出现的GUID、接口类型标记错误问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:24:02