基于WinUI 3与C#开发Win11窗口镜像应用的技术咨询
实现Windows 11窗口画面镜像的方案指引(WinUI3+C#)
优先推荐:Windows Graphics Capture API
这是微软官方推荐的现代窗口/屏幕捕获方案,PowerToys的裁剪锁定功能也基于此实现,和WinUI3的WinRT技术栈天然适配,无需处理GDI的兼容性问题,性能更优,支持Windows 10 1903及以上系统(Windows 11完全兼容)。
核心步骤:
- 配置应用权限:在
Package.appxmanifest中添加graphicsCapture能力,确保应用使用打包部署(调试阶段可使用临时证书)。 - 获取目标捕获窗口:通过P/Invoke调用
GetForegroundWindow()获取前台窗口句柄,或用EnumWindows枚举所有窗口;再通过Win32Interop.GetWindowIdFromWindow()将HWND转换为WindowId,最后用GraphicsCaptureItem.TryCreateFromWindowId()生成捕获项。 - 初始化捕获会话:先获取WinUI3应用的Direct3D设备(可通过
CompositionTarget.GetCurrentVisual().Compositor.Device获取),创建Direct3D11CaptureFramePool;再实例化GraphicsCaptureSession,关联捕获项与帧池。 - 实时渲染捕获帧:订阅帧池的
FrameArrived事件,在事件回调中取出Direct3D11CaptureFrame,通过SwapChainPanel直接渲染(硬件加速,性能最佳),或转换为SoftwareBitmap后绑定到Image控件。 - 生命周期管理:调用
GraphicsCaptureSession.Start()/.Stop()控制捕获启停,监听窗口关闭、捕获项失效等事件,及时释放资源。
备选方案:BitBlt(GDI传统方案)
若需兼容旧系统或有特殊场景需求,可使用BitBlt,但在WinUI3中需额外处理格式转换,步骤如下:
- 获取目标窗口内容:调用
GetWindowDC()获取目标窗口的设备上下文,或用PrintWindow()捕获窗口(可避免窗口被遮挡导致的捕获不全问题)。 - 内存DC与位图准备:用
CreateCompatibleDC()创建内存DC,CreateCompatibleBitmap()生成与目标窗口尺寸匹配的位图,并将位图选入内存DC。 - 执行图像复制:调用
BitBlt()将目标DC的内容复制到内存DC的位图中。 - 转换为WinUI3可显示格式:将GDI位图转换为
SoftwareBitmap,通过SoftwareBitmapSource绑定到Image控件的Source属性。 - 资源清理:使用完DC、位图后,必须调用
ReleaseDC()、DeleteObject()释放资源,防止内存泄漏。
关键注意事项
- 性能优化:优先使用
SwapChainPanel渲染捕获帧,避免软件格式转换带来的性能损耗,适合实时镜像场景。 - 窗口选择交互:可结合
GetWindowText()、GetWindowRect()实现窗口列表选择功能,或监听WM_ACTIVATE消息自动捕获前台窗口。 - 权限处理:Windows Graphics Capture首次使用时会触发系统权限弹窗,需处理授权失败的分支逻辑。
- 窗口状态适配:目标窗口最小化时,Graphics Capture会自动停止捕获,需监听窗口状态变化,恢复捕获或显示提示信息。
内容的提问来源于stack exchange,提问作者Marwan Zeyada
相关产品推荐
相关产品推荐

