尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
双击安装包之后:拆解 .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),仅供参考
RELATED

相关推荐

为什么Windows 11越用越卡?用Win11Debloat一键清理预装软件和广告,让系统重归流畅

为什么Windows 11越用越卡?用Win11Debloat一键清理预装软件和广告,让系统重归流畅

为什么Windows 11越用越卡?用Win11Debloat一键清理预装软件和广告,让系统重归流畅 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform vari…

📅 2026/10/25 16:26:37
单机环境下达梦数据守护集群的搭建

单机环境下达梦数据守护集群的搭建

注:凡是没有提到切换root用户,命令均在dmdba用户下执行 集群规划配置项实例1(主库)实例2(备库)IP地址127.0.0.1127.0.0.1实例名GRP1_RT_01GRP1_RT_02实例端口52365237MAL端口53365337MAL_DW端口54365437INS…

📅 2026/10/9 8:23:38
Windows 掌机体感调校一篇搞定:HandheldCompanion 入门体验与上手实战

Windows 掌机体感调校一篇搞定:HandheldCompanion 入门体验与上手实战

Windows 掌机体感调校一篇搞定:HandheldCompanion 入门体验与上手实战 【免费下载链接】HandheldCompanion A touch optimized GUI to increase your handheld gaming computer experience. 项目地址: https://gitcode.com/gh_mirrors/ha/HandheldCompanion …

📅 2026/10/5 18:14:06
MORE NEWS

更多资讯

📰

Unity连接MySQL显示表格:Simple TableUI实现与避坑指南

简介:面向 Unity 开发者的 MySQL 数据展示整合包,适用于在 Unity 2020.3.45f1 客户端直连数据库、读取表格数据,并借助 Simple TableUI 完成界面渲染的技术场景,尤其适合做后台管理面板、数据监控看板或本地工具类应用的中级开发者…

📰

C语言链表:从基础操作到高级应用全解析

1. 链表基础与核心概念 链表是C语言中最基础也最重要的数据结构之一,它与数组最大的区别在于内存的非连续性和动态扩展能力。想象一下火车车厢的连接方式——每节车厢独立存在,通过挂钩连接,这就是链表的生动写照。 1.1 链表的结构定义 链表…

📰

C# WinForm MQTT客户端实例:协议选型、订阅发布与避坑指南

简介:面向 C# WinForm 开发者的 MQTT 客户端实例(StdioMQTT-master),适合需要接入 MQTT 服务器、学习消息遥测传输协议,或搭建桌面端物联网验证工具的开发人员。压缩包共 121 个文件、7.82MB,含 13 个 cs 源…

📰

基于蒙特卡洛法的电动汽车充电负荷计算MATLAB仿真程序

简介:针对电动汽车充电负荷预测这一电力系统规划的关键问题,这份MATLAB程序提供了基于蒙特卡洛法的完整计算方案,面向电力系统研究人员、电动汽车方向学生及工程师,适用于充电基础设施规划与电网调度分析。程序通过大量随机抽样模…

📰

微服务架构在数据开发中的实践与优化

1. 微服务设计模式与数据开发的天然契合 数据开发领域正经历着从传统ETL管道向实时化、智能化方向的演进。在这个过程中,微服务架构展现出了与数据开发需求高度匹配的特性。我们团队在过去三年中,逐步将单体数据平台拆分为微服务架构,最直观的…

📰

A2A 1.0协议:智能体间通信的标准化解决方案

1. A2A 1.0协议概述 A2A(Agent-to-Agent)1.0协议是Google Cloud主导开发的智能体间通信开放标准。这个协议解决了一个关键痛点:在AI代理生态系统中,不同厂商开发的智能体往往采用各自封闭的通信方式,导致系统间形成信息…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬