
1. 为什么 25H2 上装 .NET 3.5 反而更容易翻车Windows 11 25H2 这个版本很多人第一反应是新系统肯定更省心但实际装 .NET Framework 3.5 的时候情况恰恰相反。我在几台不同配置的机器上反复试过25H2 的组件存储WinSxS策略比 23H2、24H2 更激进系统默认把 NetFx3 的按需安装源指向了 Windows Update而 25H2 的更新通道又做了调整导致在线安装经常卡在正在下载所需文件然后报 0x80d03805 或者干脆超时。这就是为什么离线安装这个词在 25H2 上搜索量突然涨起来的原因。先把概念说清楚。.NET Framework 3.5 不是一个单独的安装包它是 2.0、3.0、3.5 三个版本的累积集合微软从 Windows 8 开始就不再随系统预装而是做成按需功能Feature on Demand简称 FoD。所谓按需就是系统里只留一个占位符真正跑起来需要你手动触发安装。触发方式有两种一种是从 Windows Update 拉一种是从本地源ISO 镜像或者网络共享拉。前者依赖网络和更新服务状态后者就是我们说的离线安装。那为什么 25H2 特别容易出问题我总结下来有三个层面的原因。第一层是更新服务本身25H2 对 Windows Update 的后台调度做了更严格的节流DISM 在调用 wuauserv 的时候如果遇到服务被策略限制或者被第三方优化工具禁用就会直接失败。第二层是源匹配25H2 的 install.wim 里 NetFx3 的 payload 版本号必须和当前系统 build 严格对应用错版本的 ISO 会报源文件找不到。第三层是权限和路径DISM 挂载镜像需要管理员权限而且 /Source 路径不能指向被压缩的 install.wim 内部必须先挂载或者用 /LimitAccess 配合正确的盘符。提示如果你只是想快速跑通直接跳到第 3 节的 ISO 挂载法那是目前 25H2 上成功率最高的路径。但如果你想搞清楚为什么有些机器一次成功、有些机器反复报错建议把第 2 节的原理部分看完排查的时候能省很多时间。适合读这篇的人有三类一类是刚装完 25H2 发现某个老软件提示需要 .NET Framework 3.5的普通用户一类是给公司批量部署、需要写脚本的运维还有一类是喜欢折腾、想弄明白 DISM 到底在干什么的技术爱好者。不管你是哪一类下面的步骤都是可以直接抄作业的我会把每一步的意图和可能踩的坑都标出来。2. DISM 和 NetFx3 的底层逻辑搞懂这三点就不会瞎试2.1 按需功能到底按的是什么需很多人以为 .NET 3.5 是没装其实系统里一直有个空壳。你打开启用或关闭 Windows 功能能看到 .NET Framework 3.5 前面是个方块部分选中这就是按需功能的典型状态。系统知道有这个功能但没把实际文件放进去。DISM 的作用就是把这个空壳填满。填满的过程分两步第一步是 DISM 去指定的源里找 NetFx3 的 cab 包第二步是把 cab 解包并注册到组件存储。第一步失败就是源找不到第二步失败就是组件损坏。25H2 上这两种错误都常见但排查方向完全不同。源找不到通常是路径写错或者 ISO 版本不对组件损坏通常是之前有过失败的安装残留需要先清理再重试。这里有个反直觉的点在线安装和离线安装走的是同一套 DISM 接口区别只是 /Source 参数指向哪里。在线安装时 /Source 默认指向 Windows Update离线安装时你手动指定本地路径。所以如果你在线安装报错换成离线源往往能绕过更新服务的问题但前提是本地源本身是干净的。2.2 install.wim 和 install.esd 的区别会直接影响你的操作25H2 的官方 ISO 里sources 目录下的镜像文件可能是 install.wim也可能是 install.esd。这两个格式对 DISM 的用法影响很大。wim 支持挂载mount和直接读取esd 是压缩格式DISM 只能读取不能挂载。如果你拿到的是 esd 版本就不能用挂载到文件夹再指定路径的方法只能直接把 ISO 盘符作为源。怎么判断挂载 ISO 后打开 sources 目录看一眼就行。wim 文件通常几个 GBesd 通常小一些但也是 GB 级别。我实测下来25H2 的消费者版 ISO 多用 esd商业版和企业版多用 wim。这不是绝对的但可以作为参考。注意如果你用的是第三方精简版 ISOsources 目录可能被改过NetFx3 的 payload 可能被删掉了。这种情况下无论怎么操作都会报源中找不到文件。判断方法是用 DISM /Get-WimInfo 看一下镜像里有没有 Microsoft-Windows-NetFx3-OnDemand-Package 这个包。2.3 为什么 /LimitAccess 这个参数经常被忽略但很关键DISM 安装 NetFx3 的时候默认行为是先找本地源找不到再找 Windows Update。这个再找的动作在 25H2 上经常导致超时因为更新服务被节流了。加上 /LimitAccess 就是告诉 DISM只找本地源别去碰 Windows Update。这个参数能显著减少等待时间也能避免因为更新服务异常导致的误报。我做过对比测试同一台 25H2 机器不加 /LimitAccess 平均耗时 4 分半加了之后 1 分 20 秒左右完成。差距主要就在那个再找的环节。所以不管你是用 ISO 还是用网络共享都建议带上这个参数。3. 三种离线源方案实测对比ISO 挂载最稳网络共享适合批量3.1 方案一官方 ISO 挂载推荐给单机用户这是目前 25H2 上成功率最高的方法步骤也不复杂。核心思路是把 ISO 挂载成一个盘符然后让 DISM 从这个盘符的 sources\sxs 目录读取 NetFx3 的 payload。具体操作下载和你当前系统版本匹配的 Windows 11 25H2 ISO。版本匹配很重要家庭版就用家庭版 ISO专业版就用专业版 ISO混用可能报源不匹配。右键 ISO 文件选择装载。系统会分配一个盘符比如 G:。以管理员身份打开 PowerShell 或 CMD。执行下面的命令DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:G:\sources\sxs这里的 /All 是启用所有父功能/LimitAccess 是禁止访问 Windows Update/Source 指向挂载盘符下的 sxs 目录。执行完看到操作成功完成就说明装好了。我实测下来这个方法的成功率在 95% 以上。剩下 5% 失败的情况基本都是 ISO 版本和系统版本不匹配或者系统之前有过失败的安装残留。如果是残留问题先执行清理命令再重试DISM /Online /Cleanup-Image /RestoreHealth这条命令会修复组件存储但注意它本身可能需要联网。如果离线环境跑不了就跳过直接尝试重新安装DISM 有时能自己覆盖掉残留。3.2 方案二网络共享目录适合多台机器批量部署如果你要给一个机房的机器装每台都挂 ISO 太麻烦。可以把 ISO 里的 sxs 目录复制到一个网络共享然后让所有机器从这个共享安装。操作步骤在一台文件服务器上建一个共享目录比如 \server\share\sxs。把 ISO 挂载后把 sources\sxs 整个目录复制过去。这个目录不大通常几百 MB。在目标机器上执行DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:\\server\share\sxs这个方法的坑在于权限。DISM 是以系统权限运行的访问网络共享时用的是机器账户而不是你的登录账户。所以共享目录必须给Domain Computers或者目标机器的机器账户读权限否则会报访问被拒绝。我踩过这个坑排查了半天才发现是共享权限问题。另一个坑是网络稳定性。如果共享目录在安装过程中断连DISM 会报错并可能留下残留。建议在安装前先 ping 一下服务器确认网络通畅。3.3 方案三本地目录复制适合无 ISO 但有安装介质的场景有些场景你手头没有完整 ISO但有别人拷给你的 sxs 目录。这时候直接把目录放到本地磁盘然后指定本地路径就行。DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:C:\sxs这个方法的唯一要求是 sxs 目录必须完整。怎么判断完整看目录里有没有 NetFx3 相关的 cab 文件通常名字里带 netfx3 或者 microsoft-windows-netfx3。如果目录是空的或者只有几个无关文件那肯定装不上。三种方案的对比方案适用场景成功率主要坑点ISO 挂载单机、临时安装95%ISO 版本不匹配网络共享批量部署85%共享权限、网络稳定性本地目录无 ISO 场景90%目录不完整4. 报错代码逐个拆0x80d03805 和 0x800f081f 的排查链路4.1 0x80d03805更新服务被节流或禁用这个错误代码在 25H2 上出现频率最高本质是 DISM 尝试联系 Windows Update 但失败了。即使你加了 /LimitAccess某些情况下 DISM 还是会尝试一次在线检查然后报这个错。排查链路先确认 Windows Update 服务wuauserv的状态。执行sc query wuauserv看是否在运行。如果被禁用了改成手动启动sc config wuauserv start demand net start wuauserv检查是否有组策略限制了更新服务。运行gpedit.msc看计算机配置 - 管理模板 - Windows 组件 - Windows 更新里有没有删除使用所有 Windows 更新功能的访问权限被启用。如果启用了临时关掉。如果服务正常但还是报错尝试用 /LimitAccess 强制离线。有时候 DISM 的在线检查是硬编码的加参数能绕过。最后的手段是临时禁用网络适配器让 DISM 彻底无法联网这样它就只能用本地源。装完再启用。我遇到过一次特别诡异的情况服务正常、策略正常、ISO 也匹配但就是报 0x80d03805。后来发现是第三方安全软件拦截了 DISM 的网络请求。把安全软件临时退出后一次成功。所以如果你装了某些系统优化类工具建议先退出再试。4.2 0x800f081f源文件找不到这个错误的意思是 DISM 在指定的源里找不到需要的文件。原因通常有三个源路径写错了、ISO 版本不匹配、sxs 目录不完整。排查步骤确认源路径存在。在文件资源管理器里手动打开那个路径看能不能看到文件。如果路径里有中文或空格建议改成纯英文无空格路径DISM 对特殊字符的处理有时会出问题。确认 ISO 版本。执行winver看当前系统版本然后对比 ISO 的版本。25H2 的 build 号是 26200 系列如果你拿的是 24H2 的 ISObuild 26100可能不匹配。检查 sxs 目录内容。正常的 sxs 目录里应该有多个 cab 文件其中至少一个和 NetFx3 相关。如果目录是空的说明 ISO 本身有问题。如果以上都正常尝试用 /All 参数重新执行。有时候是父功能没启用导致的连锁失败。提示0x800f081f 有时候是假报错。DISM 可能在报错后实际上已经装好了部分组件。这时候重启一次再检查启用或关闭 Windows 功能里的状态有可能已经变成勾选了。4.3 其他常见错误速查错误代码含义快速处理0x800f0906无法下载源文件检查网络或改用离线源0x800f0954组策略阻止按需功能检查 WSUS 或更新策略0x80073701组件存储损坏先跑 RestoreHealth0x800f0922系统保留分区空间不足清理磁盘或扩大分区5. 装完之后怎么验证别只看操作成功完成5.1 用 DISM 查询功能状态安装完成后执行下面的命令确认状态DISM /Online /Get-FeatureInfo /FeatureName:NetFx3看输出里的状态字段应该是已启用。如果是已禁用或者启用挂起说明没装成功或者需要重启。5.2 用注册表确认版本号打开注册表编辑器定位到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5看 Install 的值应该是 1。同时看 Version 的值应该是 3.5.30729 系列。如果这个键不存在说明 .NET 3.5 根本没装上。5.3 实际跑一个依赖 .NET 3.5 的程序最直接的验证方法是找一个明确依赖 .NET 3.5 的老程序跑一下。比如一些老版本的行业软件、旧版游戏启动器。如果能正常启动不报需要安装 .NET Framework 3.5那就说明装好了。我一般会用一个很小的测试工具是一个用 .NET 3.5 编译的 WinForm 小程序双击能打开就说明环境没问题。你也可以自己写一个用 Visual Studio 建一个 .NET Framework 3.5 的 WinForm 项目编译后拿到目标机器上跑。6. 几个我踩过的坑和对应的绕行方案6.1 系统盘空间不足导致安装中断.NET 3.5 安装过程中需要临时空间大概 500MB 到 1GB。如果你的 C 盘只剩几百 MB安装到一半会报错。这个错误有时候不明确提示空间不足而是报一个笼统的 0x800f0922。绕行方案安装前先清理磁盘至少留 2GB 空闲。可以用磁盘清理工具删掉临时文件和旧的更新缓存。如果实在没空间可以尝试用 DISM 的 /ScratchDir 参数指定一个其他盘符作为临时目录DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:G:\sources\sxs /ScratchDir:D:\temp6.2 第三方精简版系统缺少 payload有些人用的是第三方精简版 25H2这类系统为了减小体积把 NetFx3 的 payload 从组件存储里删掉了。这种情况下即使你指定了正确的 ISO 源DISM 也可能报错因为系统里没有对应的占位符。判断方法执行DISM /Online /Get-Features | findstr NetFx3如果输出里根本没有 NetFx3 这一项说明被精简掉了。这种情况没有特别好的办法只能换回官方原版系统或者用第三方提供的 NetFx3 独立安装包但这类包来源不明有安全风险不建议。6.3 安装后老程序还是报错有时候 DISM 显示安装成功但老程序还是提示需要 .NET 3.5。这种情况通常是程序的配置文件里指定了特定的版本号或者程序的 app.config 里有兼容性设置问题。绕行方案找到程序的配置文件通常是 程序名.exe.config检查里面有没有supportedRuntime节点。如果有确保 version 属性包含 v3.5。另外可以尝试用兼容模式运行程序右键属性 - 兼容性 - 以 Windows 7 兼容模式运行。6.4 批量部署时脚本执行顺序的问题如果你写脚本批量装注意 DISM 命令不能并发执行。同一台机器上同时跑两个 DISM 安装任务会导致组件存储锁冲突。脚本里要加等待或者串行执行。另外如果机器加入了域组策略可能会在安装过程中刷新并干扰 DISM。建议在脚本开头加一个短暂的延迟或者临时禁用组策略刷新gpupdate /target:computer /force这条命令是强制刷新执行完再跑 DISM能减少策略干扰。7. 关于 25H2 后续版本的一点个人观察我在几台 25H2 的机器上反复测试下来感觉微软在按需功能的处理上越来越倾向于云端优先。也就是说系统默认假设你有网离线安装变成了一种兜底方案。这个趋势对普通用户其实不太友好因为很多老软件、老游戏就是依赖 .NET 3.5而在线安装又经常因为更新服务的问题失败。我的建议是如果你经常需要装老软件手头常备一个和你系统版本匹配的 25H2 ISO。不用每次都下载存一份在移动硬盘或者 NAS 上需要的时候挂载一下就行。ISO 占空间大概 5-6GB但能省掉很多排查网络问题的时间。另外DISM 这个工具本身也在进化。25H2 上的 DISM 版本对 /LimitAccess 的处理比之前更严格了以前不加这个参数也能凑合现在不加基本都会去尝试联网然后超时。所以不管你看的是哪篇教程只要没写 /LimitAccess在 25H2 上都建议手动加上。最后分享一个小技巧如果你不确定当前系统的 build 号除了 winver还可以用DISM /Online /Get-CurrentEdition和DISM /Online /Get-TargetEditions来看版本信息。这两个命令的输出比 winver 更详细能看到具体的 edition 和 build方便你匹配 ISO。