双击安装包之后:拆解 .NET Windows Desktop Runtime 的 4 层安装链

发布时间:2026/8/20 15:06:23
双击安装包之后:拆解 .NET Windows Desktop Runtime 的 4 层安装链 双击安装包之后拆解 .NET Windows Desktop Runtime 的 4 层安装链【免费下载链接】windowsdesktop项目地址: https://gitcode.com/gh_mirrors/wi/windowsdesktop.NET Windows Desktop Runtime 是一个开源的 Windows 桌面运行时工程它把 WinForms 与 WPF 桌面应用运行所需的运行时、程序集、原生依赖和安装界面统一打包进一个开箱即用的安装程序。这篇文章不打算泛泛介绍它有多强而是带你钻进安装包内部看看一次双击之后究竟发生了什么。一次双击、两个模块进度条背后是场接力赛把安装包发给朋友之前你大概早就习惯了这套流程双击、看进度条、等到安装成功、点完成。整个过程不过两三分钟看起来像一次不需要动脑的自动操作。但如果你好奇地追问一句这两三分钟里到底装了什么答案就藏在项目的两个模块里bundle 模块src/windowsdesktop/src/bundle/负责把各个组件拼装成最终的多语言安装包并定义安装界面sfx 模块src/windowsdesktop/src/sfx/负责把 WinForms 和 WPF 的程序集与原生依赖整理成可供 SDK 引用的 Ref 包和运行时使用的 Runtime 包。这两个模块一个管怎么装一个管装什么。我们顺着安装包的文件结构从第一份关键文件看起。4 层组件链bundle.wxs 里的安装剧本安装器的核心剧本写在 bundle.wxs 里。它用一段Chain定义了安装顺序像盖楼一样层层递进顺序组件备注1Microsoft .NET Host一切的地基宿主程序2Microsoft .NET Host FX Resolver依赖 Host负责解析框架3Microsoft .NET Runtime依赖前两者核心运行时4Microsoft Windows Desktop Runtime依赖以上全部最后的装修层这 4 层必须严格按依赖顺序安装先有 Host 才有解析器先有运行时才有桌面运行时。更贴心的是整条链外面包了一个RollbackBoundary——意味着中途任何一步失败前面装好的东西都会整体回滚不会给用户留下一台半残的机器。还有一个容易被忽略的细节无论最终安装包面向 x86、x64 还是 arm64Burn 引导程序本体都固定使用 x86 编译见 bundle.wixproj 中的注释这是为了让引导程序在任何架构上都能先跑起来再判断该装哪一版。版本号第 4 段数字50000 背后的升级密码如果只把组件装完就收工那还称不上省心。真正体现工程心思的是版本号第 4 段数字的设计它藏在 Wix.targets 里。规则很简单预览版Preview/RC的第 4 段用构建日期戳正式版GA/RTM则统一用 50000。由于 50000 永远大于任何日期戳这就天然保证了升级顺序Preview → RC → RTM → 后续 Servicing 更新。同一时间SuppressDowngradeFailure在预览阶段开启、在正式版关闭——预览用户允许跨版本尝试正式版则坚决拒绝降级。同时每个架构、每个大版本都会基于一个固定种子字符串生成独立的UpgradeCode。这意味着 x64 和 arm64 的安装包互不干扰可以在一台机器上并行共存而你手动升级旧版本时安装器也能通过UpgradeCode精准找到并替换掉旧版本。3 种架构的房间检查装错位宽是第一翻车现场Windows 桌面开发最常见的翻车现场就是我明明装了运行时怎么还提示缺运行时——十有八九是位宽没对上。项目对此做了非常严格的检查。在 bundle.wxs 里安装器会分别探测 x86、x64、arm64 三个房间的安装位置先查注册表SOFTWARE\dotnet\Setup\InstalledVersions再查默认目录下的dotnet.exe而且所有注册表查询都显式指定了位宽Bitnessalways32/Bitnessalways64防止在 64 位系统上误读 32 位注册表视图。更有意思的是代码里还有几段bal:Condition专门检查DOTNETHOME_X64、DOTNETHOME_X86、DOTNETHOME_ARM64这几个安装路径是否互相冲突。简单说如果检测到 x86 和 x64 的运行时被装进了同一个目录安装器会直接拦住并给出提示除非你显式传入DOTNETHOMESIMILARITYCHECKOVERRIDE来确认我知道自己在做什么。位宽检查的完整清单可以在 dotnet-packages.wxs 里看到——它给 Host、HostFxr、Runtime 三件套各自定义了一套按架构区分的探测逻辑。14 种语言多语言安装界面是这样打包的安装界面也绝不是一套英文打天下。打开 theme/ 目录你会看到 14 个以 LCID 命名的子目录2052简体中文、1028繁体中文、1031德语、3082西班牙语、1036法语、1041日语、1042韩语……每个目录下都有一份thm.wxl本地化文件对应一种语言的按钮、标题、许可文本。而界面长什么样由 bundle.thm 这份主题文件决定。它定义了安装向导的 6 个页面帮助、安装、进度、修改、成功、失败包括字体、字号、颜色和按钮布局。文件里还有两个很较真的细节自定义颜色必须保证对比度不低于 4.5:1照顾高对比度主题和弱视用户窗口左侧的 Logo 特意使用 256x256 的大图因为在高 DPI 缩放到 200% 时它比小图更清晰。想给公司定制安装界面改这一份主题文件加对应语言的 wxl 就够了。sfx 模块的两个盒子Runtime 包与 Ref 包的分工前面讲的是怎么装现在看装什么。sfx 模块里有两个并排的工程文件像一深一浅两个盒子Microsoft.WindowsDesktop.App.Runtime.sfxproj文件产出 Runtime Pack。它逐一登记 WPF 特有的原生依赖wpfgfx_cor3.dll、D3DCompiler_47_cor3.dll、DirectWriteForwarder.dll、PenImc_cor3.dll等等也登记 WinForms 与 WPF 共用的System.Diagnostics.EventLog.Messages.dllMicrosoft.WindowsDesktop.App.Ref.sfxproj文件产出 Targeting Pack即引用程序集并声明支持的运行时标识win-x64、win-x86、win-arm64。两个盒子的货最终通过 PackageOverrides.txt 里的两行占位符合并${RuntimeWindowsDesktopPackageLibraries}加上${WinformsWindowsDesktopPackageLibraries}把运行时公共库和 WinForms 专属库拼在一起。这里有个对普通开发者最友好的事实写在这份 PACKAGE.md 里你不需要单独安装 Ref 包。只要你用 .NET SDK 创建 WinForms 或 WPF 项目这个引用包会被自动包含打开项目就能直接使用System.Windows.Forms和System.Windows命名空间。避坑清单5 个最常见的安装误区把以上内容浓缩成一份问答基本就是实际部署时的高频问题Q1装完运行时应用还是提示缺桌面运行时先确认位宽。x86 应用要装 x86 版运行时x64 应用要装 x64 版arm64 同理。项目里所有注册表探测都区分了位宽安装器会尽力帮你匹配但如果你手动覆盖了安装路径就要自己为这个错误负责了。Q2一台机器能同时装 x86 和 x64 吗可以这也是项目刻意设计的结果。每个架构有独立的UpgradeCode和独立的DOTNETHOME_*变量前提是装到不同目录。如果路径冲突安装器会给出明确提示而不是默默覆盖。Q3预览版装到一半正式版出了要卸载重装吗不用。版本号第 4 段的设计保证了 Preview → RC → GA → Servicing 的平滑升级路径正式版50000永远排在预览版日期戳后面安装器会按UpgradeCode自动完成替换。Q4Reference 包Ref需要手动下载吗不需要。它是 .NET SDK 的一部分建好 WinForms/WPF 项目就能用详见 PACKAGE.md。Q5安装到一半断电了怎么办RollbackBoundary会回滚已经安装的部分避免留下损坏的运行时状态。把悬念留给你这 3 分钟值得亲自读一遍现在回到开头那个问题双击安装包之后的两三分钟里发生了什么答案是一次 4 层组件的接力安装、一场针对 3 种架构的位宽体检、一段用第 4 段版本号守护的升级逻辑外加一个支持 14 种语言的安装界面最后以事务回滚兜底收场。你看到的进度条背后是一个开源工程对装完就能跑这件事的较真。如果你也想亲手验证这份剧本可以克隆这个仓库git clone https://gitcode.com/gh_mirrors/wi/windowsdesktop然后打开 bundle.wxs 和 Wix.targets 读一遍注释——你会发现让桌面应用部署从折磨人变成无感靠的不是魔法而是这些写进文件里的细枝末节。【免费下载链接】windowsdesktop项目地址: https://gitcode.com/gh_mirrors/wi/windowsdesktop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考