
简介是一份面向 Windows Server 2012 R2 与云主机运维人员的 .NET Framework 3.5 离线安装源文件包主要解决添加系统功能时提示找不到源文件、要求使用“源”选项指定还原文件位置等常见故障适合在内网隔离、无法直连系统更新或镜像被精简的服务器上完成组件部署的初中级管理员参考使用。压缩包共 1568 个文件、约 99.19MB以 720 个 dll、180 个 resx、84 个 exe 作为核心运行组件同时包含 66 个 aspx、60 个 config、56 个 sql、50 个 browser 以及 ini、tlb、targets 等配置、脚本与资源文件覆盖运行库、管理页面、数据库脚本和浏览器适配等多类内容目录层次较完整便于按组件类型核对与检索。已有 10328 人学习下载。对于反复遇到安装源缺失、组件还原失败或云服务器功能不可用的读者这份资料可作为离线源与排错参照帮助快速定位所需文件、检查包体完整性并缩短离线部署与故障排查的周期。1. 装不上 .NET 3.5一个看着点两下就好的坑卡了整整两天在一台装着 Windows Server 2012 的机器上装 SQL Server向导走到「安装程序支持规则」那一步一行红字横在那儿需要 .NET Framework 3.5 SP1。回到「启用或关闭 Windows 功能」里把 .NET Framework 3.5 勾上转了几分钟弹出来 0x800F0906换一台机器再试同样的勾选这次给的是 0x800F081F。明明是系统自带的组件却成了整台机器上线前最难翻过去的一道坎。这类「无法安装 .NET 3.5」的故障在内网、离线、被安全基线改过的服务器上几乎必踩新手照着图形界面点会一直转圈熟手如果不去看 CBS 日志也容易在错误码之间绕圈。下面按我实际处理的顺序写先把错误码分清再看服务器上那几种常见拦截最后落到 SQL Server 依赖这条线。2. 报错 0x800F0906 与 0x800F081F系统去联网找源找的不是你以为的地方.NET Framework 3.5 在 Windows 8 / Server 2012 之后不再是「预装好躺在那儿」的组件它的功能负载被拆成了按需安装的包默认路径是从 Windows 更新拉取。图形界面里那个勾选框背后跑的就是「联网下载 cab 包 CBS 安装」这一套流程而绝大多数服务器根本没有出网权限或者更新源被改到了一个不提供功能包的内部服务上。于是你看到的是一个非常反直觉的画面组件明明是系统自带的装它却要联网。搞清这一点后面所有错误码都能对上号。2.1 错误码不是一回事先分清再动手同一句「无法安装 .NET 3.5」背后的错误码指向完全不同的两个方向一个是「拿不到」一个是「没有」。分不清就动手最常见的翻车是明明源路径写错了却跑去改组策略改完重启再试报错从 0x800F0906 变成 0x800F081F白折腾一晚上。错误码字面含义真实原因优先动作0x800F0906无法下载源文件出网不通、更新源不可达、代理拦截改用本地源0x800F081F找不到源文件/Source 路径不对sxs 目录缺失或为空核对路径与文件0x800F0907组策略不允许组件修复策略禁止联系更新查 Servicing 策略0x800F0954更新被服务端拦下WSUS 不提供功能包放行或改本地源这张表我基本是背下来的。0x800F0906 出现时说明系统知道要什么、也去拿了只是拿不到0x800F081F 出现时说明系统已经在读你给的路径了只是那条路径上没有它要的东西。两者的处理动作方向相反一个要换通道一个要修路径。0x800F0907 和 0x800F0954 更隐蔽图形界面只会给你一句「Windows 无法完成请求的更改」不看日志根本猜不到是策略层拦的。看日志的位置固定C:\Windows\Logs\DISM\dism.log记录 DISM 会话C:\Windows\Logs\CBS\CBS.log记录组件安装的每一步。搜错误码比通读快得多:: 以管理员身份打开 CMD在 CBS 日志里定位最近一次 NetFx3 安装的失败点 findstr /i /c:0x800F0906 /c:0x800F081F %windir%\Logs\CBS\CBS.log这条命令会把日志里出现这两个码的行全部打出来通常还能顺带看到它尝试访问的源路径路径一眼就能看出是不是指向了一个内网地址或者某个已经下线的共享目录。要注意 CBS.log 会持续追加跑久了有几十兆用 findstr 过滤比用记事本打开强太多。2.2 图形界面为什么永远在转圈图形界面勾选走的是「Windows 更新作为源」这条路它在后台做的事是向更新服务请求 NetFx3 的功能负载 → 拿到 cab → 交给 CBS 安装。中间任何一环断了界面表现都是同一个——进度条走一会儿回滚然后弹一个笼统的失败提示。它不会告诉你卡在请求还是卡在解包这就是很多人反复点「重试」的原因。更麻烦的是超时。有些内网机器并不完全断网而是能解析到更新服务的域名、但连接被防火墙静默丢弃这种情况下图形界面会等很久等到超时再回滚一轮下来十几分钟。如果同一台机器还要装 SQL Server等于把等待时间翻倍。我现在的习惯是只要确认是离线或者半离线环境根本不点那个勾选框直接从命令行指本地源省掉一轮不确定性。还有一类容易被忽略的情况是系统盘空间和组件存储WinSxS的状态。组件安装最终要往 WinSxS 里写东西如果之前有补丁装了一半失败或者系统盘被清理工具动过CBS 会在更靠后的阶段失败错误码可能落在别的号段上但表现仍然是「装不上 3.5」。所以看到失败先别急着换源先把日志里第一个报错点找出来那是根因后面的都是连锁反应。2.3 用 DISM 指定本地源一条命令的标准写法正确做法是把系统镜像挂载或解压到本地把源指向镜像里的sources\sxs目录同时用/LimitAccess明确告诉系统「不要再去联网找」。这条命令是整个排查过程里最值得背下来的一条。:: 假设系统镜像已挂载到 D: 盘sources\sxs 目录可直接访问 :: /All 表示同时安装该功能的所有父功能依赖 :: /LimitAccess 阻止 DISM 回退到 Windows 更新 DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /Source:D:\sources\sxs /LimitAccess参数逐个说清楚/Online指操作当前运行的系统不是离线镜像/FeatureName:NetFx3是 .NET Framework 3.5 在组件库里的固定名称注意不是 NetFx35 也不是 DotNet35/All会把 NetFx3 依赖的父功能一并启用漏了它有时会提示父功能未启用/Source必须精确指到包含 cab 文件的那一层目录指到D:\sources或者D:\都会报 0x800F081F/LimitAccess是关键不加的话即使给了本地源DISM 在某些补丁级别下仍会尝试联网校验在半通网环境里会拖很久。执行完正常情况下会看到「操作成功完成」进度条走到 100%。如果这时仍然报 0x800F081F先别怀疑命令去核对目录内容:: 确认 sxs 目录里确实有 NetFx3 的功能负载文件 dir /b D:\sources\sxs\*netfx3*正常情况下至少能看到一个名字里带microsoft-windows-netfx3-ondemand-package的 cab。如果这条命令什么都没输出说明你手上这份镜像本身就是被精简过的sxs目录是个空壳这就不是命令能解决的问题了得换一份完整的安装介质或者用一份干净的源目录顶上去。2.4 装完不等于装对三条命令确认功能真的落地DISM 报「操作成功完成」只代表安装动作结束了不代表这台机器上的应用能正常用它。我见过装完状态是 Enabled、但 ASP.NET 相关组件没注册、SQL Server 安装程序仍然报缺组件的情况。所以装完固定跑三条验证。第一条查功能状态:: 查看 NetFx3 当前状态State 应为 Enabled DISM /Online /Get-FeatureInfo /FeatureName:NetFx3第二条查注册表标记Install值应为 1带 SP1 的机器上SP值也应为 1:: 3.5 的安装标记在 NDP\v3.5 下注意不是 v4 或 v4.0 reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 /v Install reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 /v SP第三条针对要跑 Web 应用或者 SQL Server 报表服务的机器确认 ASP.NET 2.0 已经注册到 IIS:: 在 Server 2012 上 aspnet_regiis -i 已被弱化用 -ir 更稳妥 %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -ir三条都过才算这次安装真正收尾。只跑第一条就下结论是后面「明明装好了 SQL Server 还报错」的最常见来源。3. 服务器上更常见的三种拦截组策略、WSUS 和被清理过的 SxS同样的命令在开发机上一次成功在客户的生产服务器上可能连着报三个不同的错。差别不在命令在环境。服务器普遍有三层额外的管控组策略、内部更新服务、以及交付时被裁过的系统镜像。这三层里任何一层生效DISM 的默认行为都会被改掉。下面三个场景是我遇到频率最高的每个都给定位方法和解法。3.1 组策略把更新源指到了一个已经下线的内网地址现象是 DISM 加了/LimitAccess依然失败或者图形界面报 0x800F0907。原因通常是某条安全基线里配置了「指定可选组件安装和组件修复的设置」把备用源路径写成了一个早已下线的文件共享同时勾了「从不尝试从 Windows 更新下载负载」。定位靠两条命令。先看策略有没有下发:: 导出当前生效的策略搜 Servicing 相关项 gpresult /h %temp%\gp.html然后用注册表确认实际生效的值比翻策略树快:: UseWindowsUpdate: 0不检查更新 2从不联系更新 :: RepairContentServerSource: 1仅用备用源 2优先备用源 reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing /s如果看到RepairContentServerSource为 1且AlternateSourcePath或对应的源路径项指向一个访问不了的 UNC 路径那就是它了。解决办法有两个方向一是临时从域里摘出来或者用本地策略覆盖二是把一份干净的 sxs 目录放到那个 UNC 路径下——后者在有集中管控的环境里更现实因为改策略往往要走变更流程。我一般先问一句「这个路径现在还有人维护吗」多数时候答案是没人维护了。提示临时覆盖策略后记得改回去。有次我在测试机上把策略清了忘了恢复两周后另一批机器补丁装不上查了半天才发现是同一个策略项。3.2 WSUS 分类里没勾功能包服务器永远「无可用源」报错 0x800F0954。这个码的意思是「更新被服务端拦下来了」典型场景是机器加入了 WSUS 管理客户端的更新源被强制指向内部服务器而内部服务器同步的分类里不包含按需功能那一类。客户端老老实实去问服务端回答「我这儿没有」于是安装失败。先确认客户端是不是被强制走内部源:: UseWUServer1 表示更新走内部服务器而非公网 reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer返回 1 就基本锁定了。接下来两条路一是让管理员在内网更新服务里补上按需功能相关的分类并同步二是本机用本地源绕过——绕过的关键是/LimitAccess这个参数它会阻止 DISM 去问更新服务。如果加了它还报 0x800F0954说明策略层做了更硬的拦截得从Servicing那组注册表项入手。这条坑最难受的地方在于它「看起来很健康」机器能正常打补丁系统更新一切正常唯独装 .NET 3.5 不行。很多人因此排除了更新服务的问题转头去查镜像绕一大圈。3.3 镜像被精简过sources\sxs 里只剩空壳交付环境里拿到的系统镜像经常被裁剪过sources\sxs目录被清空或者只留几个无关的包用来压体积。这时候前面所有参数都写对结果还是 0x800F081F。判断方法很直接数一数目录里有多少东西:: 列出 sxs 目录下所有 cab 包只看 NetFx3 相关的 dir /b D:\sources\sxs\*.cab | findstr /i netfx3没有输出就说明这份介质里根本没有 3.5 的负载。注意不能拿别的版本的 sxs 目录凑合组件包的版本必须和目标系统的版本、补丁级别对得上跨版本塞进去大概率在 CBS 阶段校验失败报出来的错又是另一个号码。我踩过一次手边只有一份更新版本的镜像觉得「都是 3.5应该通用」结果装到一半回滚日志里一堆哈希校验相关的失败。后来老老实实找回对应版本的介质一次过。这件事之后我养成一个习惯——离线环境里常备一份和目标系统版本严格对应的 sxs 目录放在本地磁盘上需要时直接把源指过去比每次找镜像快得多。资源包里那份整理好的离线源目录就是干这个用的目录结构按sources\sxs组织好挂上或者解压后把/Source指过去即可省掉找介质和对版本的环节。3.4 三条命令定位到底卡在哪一环同时面对策略、更新服务、镜像三个变量时按下面的顺序排查能在一两分钟内缩小范围。第一步看机器是不是被策略管着gpresult /h里搜 Servicing 和 WindowsUpdate 两组关键词。第二步看更新源的实际指向wuauclt /reportnow之后查注册表里的服务端地址。第三步看介质完整性dir数 cab 包。三步走过去结论基本唯一策略拦的改策略服务端拦的绕服务端介质缺的换介质。命令本身不难难的是顺序。先查介质再查策略等于在最不容易出问题的一环上花时间。我现在固定按「策略 → 源 → 介质」这个顺序走因为前两项在服务器上出问题的概率加起来远高于第三项。4. SQL Server 装着装着提示要 .NET 3.5 SP1顺序、共存与补丁级别.NET 3.5 装不上的很大一部分场景其实不是有人主动去装它而是装别的软件时被要求装。SQL Server 的安装程序就是这个「触发器」——它的支持规则检查会明确列出缺少的组件其中 .NET Framework 3.5 SP1 是最常出现的一条。这一章把这个链条讲清楚为什么装 SQL Server 会牵出 3.53.5 和 4.x 是什么关系以及装完 3.5 之后仍然报错该往哪儿看。4.1 安装检查项报红先看它到底要的是哪个组件SQL Server 安装向导走到「安装程序支持规则」时会做一轮环境检查缺组件会以警告或失败的形式列出来。这里有个容易误判的点提示语写的是「需要 .NET Framework 3.5 SP1」但不同版本的安装程序对 SP 级别的要求不完全一样有的组件比如某些管理工具和报表相关组件对 3.5 的依赖是硬性的有的只是警告、可以跳过继续。所以第一步不是急着装而是看清楚它是「失败」还是「警告」。失败项必须补齐才能往下走警告项可以先记下来装完主程序再补。我见过有人为了消掉一条警告在已经装了 4.x 的机器上折腾了半天的 3.5最后发现根本不影响主流程。如果确实是失败项就按第 2 章的方法把 3.5 装上然后再回到安装程序点「重新运行」检查。注意 SQL Server 的检查器有缓存补完组件后最好退出向导重进而不是在原界面上直接重试。4.2 3.5 和 4.x 是并行的两套运行时这是最容易被误解的一点装了 .NET 4.5 或者 4.8不等于 3.5 就有了。两套运行时在系统里是并存关系各自有独立的程序集目录、独立的注册表分支、独立的 CLR 版本。4.x 不能向下替代 3.5装了更高版本也不会让「需要 3.5」的检查消失。注册表上能直观看到这种并行:: 两套运行时的安装标记分别在各自的分支下互不影响 reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 /v Install reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full /v Releasev4\Full下的Release是一个数值不同数值对应不同版本这个值可以用来确认 4.x 的补丁级别而 3.5 只有Install和SP两个关键标记。两条命令都返回正常才说明两套运行时都在位。还有一层IIS 里的应用程序池是按运行时版本分的。装完 3.5 之后如果站点要跑 ASP.NET 2.0还得确认对应应用池选的是 2.0 而不是 4.0。装组件和配应用池是两件事只做前一件站点照样起不来。4.3 装完 3.5 后 SQL Server 还报错看 SP 级别和后续补丁组件装上了、状态 Enabled、注册表也对安装程序依然提示缺 3.5 SP1。这种时候通常不是 3.5 没装而是补丁级别没到。.NET 3.5和.NET 3.5 SP1在注册表上只差一个SP值系统层面DISM报的是 Enabled看起来完全正常。但某些安装程序检查的是 SP 值是否为 1或者检查特定版本的程序集文件是否存在。前面给过查询命令SP值为 0 或者查询不到就说明这台机器上是 3.5 的原始版本需要打对应的服务包。判断办法是直接查文件版本比看注册表更接近真相# 查看核心程序集的实际文件版本SP1 之后版本号会有明显提升 (Get-Item $env:windir\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll).VersionInfo.FileVersion这条 PowerShell 返回的是文件版本号和注册表里那些标记互为印证。如果注册表说 SP1、文件版本却是早期的说明装的包不完整或者来自一份被裁剪过的源得换源重装。反过来如果文件版本对、安装程序还报错那问题就转移到安装程序自身的检查逻辑上可以查它的引导日志——SQL Server 安装程序的详细日志默认在临时目录下里面有它逐条判断的结果比界面上的红叉具体得多。4.4 确认 3.5 真的可用注册表、程序集、ASP.NET 三板斧装完组件和「应用能用它」是两件事尤其在这台机器还要跑 SQL Server 的情况下。我固定做三个验证缺一个都不放心。第一板斧是注册表前面已经给过命令Install和SP都要对。第二板斧是程序集加载用 PowerShell 直接尝试加载 2.0 的核心程序集加载失败说明运行时有实际问题# 尝试加载 3.5 对应的核心程序集能拿到对象说明运行时正常 $asm [System.Reflection.Assembly]::LoadWithPartialName(System.Web) if ($asm) { loaded: $asm.FullName } else { load failed }这里用的是部分名称加载走的是旧版程序集解析路径正好能验证 2.0 运行时的可用性。第三板斧是 IIS 注册如果这台机器上要部署 Web 组件aspnet_regiis.exe -ir跑一遍然后在 IIS 里确认 ASP.NET 2.0 的功能已经启用。三板斧都过再去启动 SQL Server 安装程序检查项就应该全绿了。如果还是红那问题多半不在运行时而在安装程序自身的前置条件或者权限上本节前面提到的引导日志就是下一个去处。5. 避坑清单装 .NET 3.5 时最容易翻车的五个地方这一章把前面散落各处的坑集中列一遍每条按「现象 → 原因 → 解决」写都是我自己或者身边人真实翻过的车。遇到卡住的时候先扫一遍这张表比从头推理快。5.1 源路径指到了 sources 这一层报 0x800F081F现象命令照抄参数也加了/LimitAccess执行后立刻报找不到源文件。原因/Source必须精确指到包含 cab 的那一层目录。指到D:\sources、指到镜像根目录、甚至指到D:\sources\sxs\但目录里实际是空的都报同一个码。系统不会告诉你「差一层」它只会说找不到。解决先dir /b D:\sources\sxs\*netfx3*确认文件在再确认路径里没有多余的层级和拼写错误。我建议直接把路径复制到命令里手敲sources敲成source这种错误我见过不止一次。5.2 用 WinRAR 解压镜像结果是「文件都在但装不上」现象把 ISO 用解压工具解出来sxs目录文件齐全DISM 却报各类哈希或校验失败。原因部分解压工具对 ISO 里的长文件名、特殊字符处理有问题个别文件解出来是损坏的或者大小写被改动。cmp 一下文件数可能都对得上但内容已经不一样了。解决用系统自带的挂载功能挂载 ISO或者用/Source指向网络共享上未经压缩的原始目录。已经解压的直接重新挂载一份覆盖别在原目录上修修补补。5.3 装完重启功能状态变回 Disabled现象DISM 报成功后机器重启再查状态又回到未启用SQL Server 依然报缺组件。原因装完立刻有补丁或者配置管理任务介入把组件状态改了更常见的是机器上有组策略或者第三方配置管理工具在做「基线还原」把系统功能列表重置回基线定义的状态。解决先确认是不是有基线在跑把 3.5 加进基线允许列表再重新执行安装。否则装几次都会被还原回去这类问题最磨人因为每次看起来都成功了。5.4 同时装多个运行时顺序搞反导致安装程序卡住现象在一台新机器上先装 3.5 后装 4.x或者反过来装第二个时安装程序卡在初始化不动。原因运行时的安装程序会互相检查版本和依赖某些组合下会触发重启要求不重启直接装下一个就会卡。解决装完一个就重启一次别图省事连着装。确认前一个的注册表标记正常再动下一个。这条没什么技巧纯粹是顺序纪律。5.5 用在线方式在没网环境硬试浪费一整天现象图形界面勾选后一直转圈超时回滚再点再转圈一天过去什么都没装上。原因没意识到图形界面走的必然是在线通道。离线或者半离线环境里这条路从设计上就走不通重试多少次结果都一样。解决只要判断出环境不能正常访问外部更新源直接放弃图形界面改用 DISM 加本地源。判断方法很简单看更新服务能不能连上、机器有没有出网权限两分钟就能确认省下的时间够把整台机器装完。6. 三步定位先判断该修源、该改策略还是该换介质排查这类问题时最容易浪费时间的是「猜」。猜是策略问题就去翻策略猜是镜像问题就去换镜像来回试。实际上三步就能把范围收窄到唯一方向我现在的固定流程是这样。第一步看错误码落在哪个号段。0x800F0906 和 0x800F0907 指向「通道」问题前者是拿不到、后者是被策略禁止0x800F081F 指向「内容」问题路径或文件缺失0x800F0954 指向「服务端」问题。这一步决定了后面查哪里做对了能省掉一半时间。错误码不要只看弹窗弹窗有时给的码是包装过的去 CBS 日志里找原始的失败记录更准。第二步验证源的真实可用性。不管错误码是什么都用一条 dir 命令确认你手上的源目录里确实有对应版本的 cab 文件再用DISM /Online /Get-FeatureInfo /FeatureName:NetFx3看当前功能状态。这两条命令加起来十秒能排掉「源本身就不行」这个最常见的前提错误。第三步看策略层的实际生效值。前面给过的两组注册表查询Servicing和WindowsUpdate\AU一目了然地告诉你这台机器是被谁管着的。如果发现策略指向了一个失效地址那就是根因如果策略干净、源也对、还是失败那就该怀疑补丁级别或者基线还原往第 4 章和第 5 章的方向走。观察到的信号指向的根因下一步动作0x800F0906 无出网权限更新源不可达改本地源加 /LimitAccess0x800F081F sxs 为空介质被精简换完整介质或干净源目录0x800F0907 Servicing 有策略策略禁止联网覆盖策略或补备用源0x800F0954 UseWUServer1内部更新服务不提供功能包绕过服务端走本地源DISM 成功但重启后回退基线还原把功能加入基线允许列表状态 Enabled 但安装程序仍报错SP 级别或程序集不完整查文件版本补齐服务包这张表不是给你背的是给卡住的时候对照用的。多数故障在前两行就能定位剩下的属于环境特例。最后说个习惯。这套流程走顺之后我每次接手一台新服务器在装任何依赖 .NET 的软件之前都会先花两分钟跑一遍状态查询把 3.5、4.x 的注册表标记和功能状态记下来。有过一次在客户现场因为没提前确认装到半夜才发现机器上的 3.5 是残缺的只能第二天重新找介质。从那以后这个前置检查我一次都没省过两分钟换一晚上的踏实很值。资源包里那份整理好的离线源目录和命令就是按这套流程准备的——挂上源、指路径、跑验证三步走完。希望帮到你。本文还有配套的精品资源点击获取