WinUI 3 + Windows 系统还原工具开发实战与微软平台反思
技术挑战与细节
在开发 WinUI 3 桌面应用时,我们遭遇了多项痛点。首先,XAML 控件有很多新规则,例如 ContentDialog 必须手动设置 XamlRoot 才能显示,否则会抛出错误消息(例如"This element is already associated with a XamlRoot")。一开始没注意到这点,就可能导致对话框无法弹出。对于系统还原功能本身,Windows 提供了 SRSetRestorePoint 之类的 Win32 API,以及对应的 WMI 类。然而,系统还原点有时效限制(新点最多只保留60天),而且必须以管理员权限执行才能成功建立还原点。这意味着应用程序要做系统还原点时,必须先取得提升权限。例如,StackOverflow 上就指出「要创建还原点必须具有管理员权限」。此外,在封装为 MSIX 或 UWP 应用后,由于 Windows 应用沙箱限制,直接调用 WMI 或 COM 类常被拒绝,需要通过 runFullTrust 等机制(也就是用桌面桥接或外部进程)来实现。
在多语系支援方面,WinUI 3 也不算轻松。需要为每种语言准备独立的 .resw 文件(放在 Strings\xx-XX 资料夹)并以 x:Uid 或 ms-resource 来引用。每次修改资源后,必须使用 MakePri.exe 重新生成 .pri 索引,否则新的字符串不会生效。微软文档建议以后制脚本自动执行 MakePri,并将输出的 resources.pri 拷贝到输出目录。遗憾的是,WinUI 3 现阶段只支援在应用启动时套用系统语系,无法像行动框架那样随时热切换。正如社群在 V2EX 上所说:「按照官方文档的说法,要先把字符串存到 resw 文件里,然后在 XAML 里引用 x:Uid ,程序就可以根据系统区域自动识别了。」如果要实现动态换语言,只好自行用 ApplicationLanguages.PrimaryLanguageOverride 再配合重载页面,或用 ResourceLoader 手动逐个更新 UI 字符串。这类折衷方案比较繁琐,也是开发者常踩雷的地方。
封装与权限也是一大挑战。WinUI 3 桌面应用预设采用Full-Trust模型,因此在 Package.appxmanifest 中通常自带 <rescap:Capability Name="runFullTrust"/>。也就是说,发佈到 Microsoft Store 时,系统会认为你使用了受限能力,要求提供理由。事实上,微软官方说「WinUI 3 应用使用全权桌面模型(full-trust),包清单若包含受限能力 runFullTrust,在提交时必须额外回答问题」。如果打包过程中遇到奇怪的资源错误,也有官方对策。例如,有时编译会出现 MSB4018 或 PRI 资源生成错误,微软文档建议在项目属性中禁用自动生成 PRI:
<AppxGeneratePrisForPortableLibrariesEnabled>false</AppxGeneratePrisForPortableLibrariesEnabled>
这可避免 MSB4018「GenerateResource 任务失败」错误。此外,我们实测过程中也碰到过莫名其妙的 resources.pri 无法复制错误(DirectoryNotFoundException),最后不得不整个重建项目才解决。
总之,MSIX 打包往往有各种陷阱,包含签名、证书、权限等要逐一排查。
微软平台观察与反思
从这次项目看 WinUI 3 和 Windows App SDK 的状况,发现它虽然带来现代化 UI 框架,但整体开发体验仍有待改进。社群评论 WinUI 3 时经常提到:开发体验差(目前无直观设计器,只能靠写 XAML,编译速度又很慢)、安装包体积大(一个空的 WinUI 3 C# 应用就有 40MB 以上)、互操作性能差(因 CsWinRT 互调开销大)、第三方生态欠佳(正式发布未满一年,可用的控件很少)。这些缺点让人感觉 WinUI 3 还没准备好做生产力工具。不少开发者吐槽:桌面端的开发体验根本比不上行动端框架的热重载和即时预览,用 WinUI 3 改东西竟要重启应用,让人「硬邦邦」。而且,微软近期才宣布将 WinUI 3 原始码「真正开源」,但进展龟速,不少人已笑称「连微软自己都没用它,叫我们怎么用?」。
对于 Microsoft Store 和应用沙箱政策的观察:Store 对 runFullTrust 的审核非常严格,我们必须在提交时说明为何需要此权限。即便 WinUI 3 不算 UWP,但凡打包为 APPX 就等于自带了全权能力。这使得开发者常要妥协,比如有经验的同学抱怨:「根本无法去除这个设置,发佈时只能跟审核员解释『这是官方 msix 打包机制』。」对于原始的 WMI 或 COM 接口,则只能通过引入 runFullTrust 的 Out-Of-Process COM 或 Powershell 来间接使用(等于变相叫系统做事),无形中大大增添了复杂度。此外,桌面应用现在有 WinForms、WPF、UWP、WinUI、控制台等多项技术并存,缺乏单一统一方向。正如外媒所评价的:「每隔几年就推出新技术,很多最后被废弃;名字和路线频繁变化,让人摸不着头脑」。这种分裂现象让开发者对未来路线更感疑惑,也增添了选择成本。
综合观点与社群语气
总的来说,这次项目既让我们体验到 WinUI 3 的一些优点(现代化风格、Fluent 控件等),也暴露了诸多不一致之处。在忍耐一堆配置、权限、编译慢等问题的同时,难免对微软的技术路线生出不信任感。不少开发者调侃:为了实现一个系统还原的功能 UI,竟要「召唤出 COM、Powershell、manifest 才能执行」,感觉搞得像在召唤神兽一般。社群上常见抱怨包括「WinUI 3 稳定性不够」、「官方文件过时模糊」等,比如有人说「桌面端 WinUI 3 稍微改点东西程序就要完全重启,还惊讶启动速度慢,使用体验简直硬邦邦」。甚至有观察指出,WinUI 3 目前根本不是微软内部首选技术,「连微软自己都没用它,还叫社群用?」。面对这些,开发者常会半开玩笑半无奈地形容:「哎,这些技术弄得真复杂,到头来还不是要自己想办法吃案子。」
小结: WinUI 3 与系统还原工具的开发经历告诉我们:固然可以打造现代化的应用体验,但也要准备好面对 SDK 的各种限制与坑。从核心 API 权限、沙箱限制,到翻新不久的 UI 框架,整个过程中不断调适与迂回。对微软平台而言,希望这些反思能引导改进:提供更好的开发工具与文件、简化上架要求、统一桌面开发路线,而不是让开发者「被 WinUI3 害到内伤」般叫苦不迭。只有这样,Windows 桌面生态才能真正恢复开发者的信心与活力。