ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows Server 2012 离线安装 .NET 3.5:sxs 源配置与 DISM 实战

Windows Server 2012 离线安装 .NET 3.5:sxs 源配置与 DISM 实战 简介这份资源面向需要在 Windows Server 2012 上离线部署 .NET Framework 3.5 的运维人员与系统管理员尤其适合服务器无法联网或网络受限的企业内网环境。资源以 SXS 组件文件为核心配合 DISM 命令即可完成 NetFX3 功能的本地启用解决老应用依赖 .NET 3.5 却无法通过 Windows Update 安装的痛点。压缩包为 rar 格式整体约 85.35MB文件总数与类型明细上游暂未提供但内容围绕 SXS 存储中的 CLR、WPF、WCF 等系统组件展开可直接作为离线源使用。目前已有 935 人学习下载说明该方案在同类场景中具备一定参考价值。掌握 SXS 离线安装思路后读者不仅能完成单台服务器的框架部署还可预先准备组件包在多台机器上批量操作提升企业环境下的维护效率。1. Windows Server 2012 装 .NET 3.5 为什么总卡在 sxs 文件上在 Windows Server 2012 上跑老业务系统十有八九会撞上 .NET Framework 3.5 装不上的问题。你打开服务器管理器勾选「.NET Framework 3.5 功能」点安装进度条走两下就弹窗报错提示需要「指定备用源路径」或者干脆甩一个 0x800F0906。这不是系统坏了是微软从 2012 开始把 .NET 3.5 的安装源从系统镜像里拆了出来默认不随系统一起装必须手动提供 sxs 文件夹。sxs 就是 WinSxS 的缩写里面存的是组件存储.NET 3.5 的安装包就藏在 sources\sxs 这个目录下。搞不定这个 sxs 源后面所有依赖 .NET 3.5 的应用都跑不起来。这篇内容面向的是手里有 Windows Server 2012 或 2012 R2 的运维和开发不管你是刚接手一台老服务器还是要在新环境里复现旧系统下面这套流程能让你少走几个小时的弯路。2. 先搞清楚 sxs 源到底该从哪来2.1 系统镜像里的 sxs 和系统盘里的 WinSxS 不是一回事很多人第一次遇到这个报错第一反应是去 C:\Windows\WinSxS 里找文件结果发现那个目录根本没法直接拿来当安装源。原因在于系统盘里的 WinSxS 是已经展开并经过硬链接处理的组件存储文件结构跟安装介质里的 sources\sxs 完全不同。安装介质里的 sxs 文件夹是一堆 .cab 包和配套的清单文件专门给 DISM 或服务器管理器做按需安装用的。你拿系统盘里的 WinSxS 去指路径DISM 会直接告诉你找不到源文件。所以第一步要建立的概念是sxs 源必须来自与你当前系统版本和架构完全匹配的安装 ISO不能从已装好的系统里抠。匹配这件事有三个维度主版本号2012 还是 2012 R2、具体内部版本号比如 6.2.9200 和 6.3.9600 就不通用、处理器架构x64 和 x86 不能混。我见过有人拿 Windows Server 2012 R2 的 ISO 去给 2012 原版装 .NET 3.5DISM 报错说源文件版本不匹配折腾半天才发现是版本号对不上。所以在你动手之前先确认服务器上winver弹出来的版本信息再去找对应的 ISO。2.2 挂载 ISO 并定位 sources\sxs 的最小操作假设你已经拿到了匹配的 ISO 文件下一步是把它挂载到服务器上。如果你在虚拟机里操作直接通过虚拟化平台挂载 ISO 最省事如果是物理机可以用 IPMI 的虚拟光驱或者把 ISO 拷到服务器本地再用 PowerShell 挂载。下面这条命令是在 Windows 里挂载 ISO 的标准做法# 挂载 ISO 到虚拟光驱返回的 DriveLetter 就是盘符 $iso Mount-DiskImage -ImagePath D:\ISO\SERVER2012R2.iso -PassThru $drive ($iso | Get-Volume).DriveLetter Write-Host ISO 已挂载到 $drive 盘 # 确认 sxs 目录存在 Test-Path ${drive}:\sources\sxs这段逻辑很直接Mount-DiskImage把 ISO 挂成虚拟光驱-PassThru让命令返回对象而不是空然后从返回对象里取卷信息拿到盘符。最后用Test-Path验证sources\sxs目录是否存在返回 True 才说明这个 ISO 里有安装源。参数上唯一要注意的是-ImagePath必须写绝对路径相对路径在某些 PowerShell 版本下会解析失败。如果Test-Path返回 False说明你拿到的 ISO 可能是个精简版或者第三方修改版里面被裁掉了 sxs 目录这种情况只能换官方原版 ISO。2.3 用 DISM 指定 sxs 源安装 .NET 3.5 的完整命令挂载好 ISO 之后安装 .NET 3.5 有两种方式服务器管理器图形界面和 DISM 命令行。图形界面在指定备用源路径时经常因为路径格式问题报错我一般直接用 DISM可控性更强。命令如下# 用 DISM 从挂载的 ISO 安装 .NET 3.5注意 Source 路径指向 sxs 文件夹 DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:E:\sources\sxs # 如果上面命令报错加上 /NoRestart 先不重启方便看日志 DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:E:\sources\sxs /NoRestart这里几个参数值得展开说。/Online表示操作当前运行的系统不是离线镜像。/FeatureName:NetFx3是 .NET 3.5 在 DISM 里的功能名注意不是 NetFx35 也不是 NetFramework3.5。/All会一并安装所有父功能和依赖项不加这个有时候会提示缺少父功能。/LimitAccess是关键参数它告诉 DISM 不要去找 Windows Update只用你指定的源这样能避免系统尝试联网下载然后超时。/Source后面跟的路径必须精确到 sxs 文件夹本身不能只写到盘符或者 sources 目录。执行成功后你会看到「操作成功完成」的提示然后可以用Get-WindowsFeature Net-Framework-Core确认安装状态。3. 没有 ISO 的时候怎么凑出可用的 sxs 源3.1 从同版本系统的 WinSxS 里提取 cab 包的可行性有时候你手头确实没有安装 ISO但有一台已经装好 .NET 3.5 的同版本服务器。这种情况下可以从那台机器的C:\Windows\WinSxS里把相关的 cab 包提取出来拼成一个可用的源目录。这个做法不是官方推荐但在应急场景下确实能跑通。核心思路是找到所有microsoft-windows-netfx3-*开头的文件夹把里面的 .cab 文件复制到一个临时目录然后用 DISM 指向那个目录。# 在已装好 .NET 3.5 的源机器上执行提取 netfx3 相关的 cab 包 $dest C:\sxs_temp New-Item -ItemType Directory -Path $dest -Force Get-ChildItem C:\Windows\WinSxS -Directory | Where-Object { $_.Name -like microsoft-windows-netfx3-* } | ForEach-Object { Get-ChildItem $_.FullName -Filter *.cab | Copy-Item -Destination $dest -Force } # 统计提取了多少个 cab 文件 (Get-ChildItem $dest -Filter *.cab).Count这段脚本的逻辑是先建一个临时目录然后遍历 WinSxS 下所有名字里带microsoft-windows-netfx3-的文件夹把每个文件夹里的 .cab 文件复制到临时目录。执行完之后你会得到一堆 cab 包数量取决于系统版本通常在几十个左右。但这里有个坑WinSxS 里的 cab 包可能不完整因为有些组件已经被硬链接到其他位置直接复制出来的文件可能缺少清单或者版本不匹配。所以这个方法只适合应急装完之后最好用sfc /scannow检查一下系统完整性。3.2 用 DISM 导出已安装的 .NET 3.5 作为离线源比手动复制 cab 包更可靠的做法是用 DISM 的导出功能把已安装的 .NET 3.5 从源机器上导出成一个完整的离线源包。这个命令在源机器上执行# 在已装好 .NET 3.5 的机器上导出 netfx3 的完整源到指定目录 DISM /Online /Export-Source /FeatureName:NetFx3 /Source:C:\Windows\WinSxS /Destination:C:\netfx3_source # 导出完成后把 C:\netfx3_source 整个目录拷到目标服务器 # 然后在目标服务器上执行安装 DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:C:\netfx3_source/Export-Source这个参数的作用是把指定功能的源文件从系统组件存储里提取出来放到一个独立目录。跟手动复制 cab 包相比它会把清单文件和依赖关系一起导出所以目标机器上的 DISM 能正确识别。导出目录的大小通常在 200MB 到 400MB 之间取决于系统版本。拷到目标服务器之后/Source指向那个目录即可。这个方法的局限是源机器和目标机器的版本必须完全一致否则导出的清单文件会对不上。3.3 离线源目录的校验和常见结构不管你用哪种方式凑出 sxs 源在正式安装之前最好先看一眼目录结构对不对。一个完整的 sxs 源目录里应该包含以下几类文件文件类型命名特征作用cab 包以 .cab 结尾名字含 netfx3实际的组件安装包清单文件以 .mum 结尾描述组件依赖和版本配置文件以 .manifest 结尾组件的元数据如果你打开目录发现只有 cab 文件没有 .mum 和 .manifest那这个源大概率是不完整的DISM 执行到一半会报 0x800f081f 错误意思是找不到源文件。遇到这种情况要么换 ISO要么用/Export-Source重新导出一份完整的。4. 避坑sxs 安装 .NET 3.5 的五个翻车现场4.1 报错 0x800F0906源文件找不到现象是 DISM 执行后直接返回 0x800F0906提示「无法下载源文件」。原因通常是/Source路径写错了或者路径指向的目录里没有 sxs 文件。还有一种可能是你忘了加/LimitAccess系统尝试去 Windows Update 找源但服务器没有外网连接等超时之后就报这个错。解决办法是先Test-Path确认路径存在再检查目录里有没有 .cab 文件最后确保命令里带了/LimitAccess。4.2 报错 0x800F081F源文件版本不匹配这个错误比 0906 更隐蔽现象是 DISM 能找到源文件但安装到一半失败返回 0x800F081F。根本原因是 ISO 的版本号和当前系统对不上。比如你的服务器是 Windows Server 2012 R2内部版本 6.3.9600但你挂载的是 Windows Server 2012 原版6.2.9200的 ISO清单文件里的版本号校验就会失败。解决办法是用winver确认系统版本然后去找完全匹配的 ISO。如果实在找不到可以试试用/Source指向一个从同版本系统导出的离线源。4.3 图形界面指定源后仍然报错有些人在服务器管理器里点「指定备用源路径」填了E:\sources\sxs点确定之后还是报错。这个问题的原因通常是路径格式不对。图形界面要求路径必须是 UNC 路径或者本地绝对路径而且不能有尾部反斜杠。另外如果你把 ISO 挂载到了虚拟光驱盘符可能会变填之前先用Get-Volume确认一下当前盘符。我的习惯是直接用 DISM 命令行绕开图形界面的路径解析问题。4.4 安装完成后应用仍然提示缺少 .NET 3.5有时候 DISM 显示安装成功但跑应用的时候还是报「需要 .NET Framework 3.5」。这种情况一般是 32 位和 64 位组件没装全。Windows 的 .NET 3.5 包含 32 位和 64 位两套组件DISM 的/All参数理论上会都装上但某些精简版 ISO 里可能只包含其中一套。解决办法是分别检查Get-WindowsFeature Net-Framework-Core和Get-WindowsFeature Net-Framework-Core-32的状态如果有一个没装手动用 DISM 单独装那个功能。4.5 挂载 ISO 后盘符冲突导致源路径失效在有多块磁盘的服务器上挂载 ISO 之后分配的盘符可能跟你预期的不一样。比如你脚本里写的是E:\sources\sxs但实际挂载到了F盘。这个问题的隐蔽之处在于DISM 报的错还是 0x800F0906让你以为是源文件的问题。避免方法是不要硬编码盘符用 PowerShell 动态获取# 动态获取挂载 ISO 的盘符避免硬编码 $iso Mount-DiskImage -ImagePath D:\ISO\SERVER2012R2.iso -PassThru $drive ($iso | Get-Volume).DriveLetter $sourcePath ${drive}:\sources\sxs DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:$sourcePath这样不管系统分配什么盘符源路径都能正确拼出来。5. 用 PowerShell 做批量部署和安装后验证5.1 把安装流程封装成可复用脚本如果你管的不止一台服务器每次手动挂 ISO、敲 DISM 太费时间。我一般会写一个 PowerShell 脚本把挂载、安装、验证三步串起来。脚本接受 ISO 路径作为参数自动完成所有操作param( [Parameter(Mandatory$true)] [string]$IsoPath ) # 挂载 ISO $iso Mount-DiskImage -ImagePath $IsoPath -PassThru $drive ($iso | Get-Volume).DriveLetter $source ${drive}:\sources\sxs # 检查源目录是否存在 if (-not (Test-Path $source)) { Write-Error ISO 中未找到 sources\sxs 目录请确认 ISO 版本 Dismount-DiskImage -ImagePath $IsoPath exit 1 } # 执行安装 $result DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:$source /NoRestart # 检查安装结果 if ($LASTEXITCODE -eq 0) { Write-Host NET 3.5 安装成功 -ForegroundColor Green } else { Write-Warning 安装返回错误码 $LASTEXITCODE请检查 DISM 日志 } # 卸载 ISO Dismount-DiskImage -ImagePath $IsoPath这个脚本的关键点在于用param块接收外部参数方便批量调用安装前先Test-Path校验源目录避免无效操作安装后用$LASTEXITCODE判断 DISM 的返回码0 表示成功最后无论成败都卸载 ISO释放盘符。你可以把这个脚本存成Install-NetFx3.ps1然后在多台服务器上通过远程执行或者组策略推下去。5.2 安装后的验证命令和日志排查位置装完之后不能只看 DISM 的提示最好做一次完整验证。验证分三层功能状态、注册表项、实际运行。功能状态用Get-WindowsFeature查注册表项看HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5下的 Install 值是否为 1实际运行可以写一个简单的 .NET 3.5 控制台程序跑一下。如果验证不通过DISM 的日志在C:\Windows\Logs\DISM\dism.log用Select-String搜NetFx3或者错误码能看到具体的失败原因。# 三层验证功能状态、注册表、日志 Get-WindowsFeature Net-Framework-Core | Select-Object Name, InstallState Get-ItemProperty HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 | Select-Object Install Select-String -Path C:\Windows\Logs\DISM\dism.log -Pattern NetFx3 | Select-Object -Last 20注册表里 Install 值为 1 说明安装成功为 0 或者键不存在说明没装上。日志里最后 20 条跟 NetFx3 相关的记录能帮你定位到具体是哪一步失败的。5.3 用离线源做无人值守安装的注意点如果你要在大量服务器上做无人值守安装有几个细节需要提前处理好。第一ISO 文件要放在所有目标机器都能访问的网络路径上或者提前拷到本地固定目录。第二PowerShell 的执行策略要允许运行脚本可以用Set-ExecutionPolicy RemoteSigned临时放开。第三如果目标机器启用了 UAC远程执行 DISM 可能会被拦截建议用计划任务或者 SCCM 这类工具以系统权限运行。第四安装完成后记得重启虽然/NoRestart能让你先看日志但 .NET 3.5 的某些组件需要重启才能完全生效。我自己的习惯是在正式推之前先找一台测试机跑一遍完整流程确认 ISO 版本匹配、脚本没有语法错误、安装后验证通过再批量执行。这个习惯帮我省过好几次回滚的麻烦。希望帮到你。本文还有配套的精品资源点击获取
返回列表