)
1. 為什么 2024 年了還在跟 .NET Framework 3.5 死磕如果你手上有一臺剛裝好的 Windows 10 或者 Windows 11興沖沖地準(zhǔn)備裝某個行業(yè)軟件、老版 CAD 插件、財務(wù)客戶端、金蝶用友的某個模塊結(jié)果安裝程序彈出一句“需要 .NET Framework 3.5包括 .NET 2.0 和 3.0”然后系統(tǒng)自帶的在線安裝轉(zhuǎn)了半天進(jìn)度條最后報 0x800F0906 或者 0x800F081F這事兒就算正式開始了。Windows 10/11 離線安裝 .NET Framework 3.5看著像是個上古話題實際上到今天依然是運(yùn)維、裝機(jī)、企業(yè) IT 桌面支持最常被問到的操作之一尤其是內(nèi)網(wǎng)機(jī)器、生產(chǎn)車間電腦、隔離網(wǎng)絡(luò)里的工控終端根本連不上 Windows Update。這篇文章我打算把這塊徹底講透。適合看的人包括企業(yè) IT 運(yùn)維、給客戶裝機(jī)的技術(shù)支持、經(jīng)常折騰開發(fā)環(huán)境的人、以及被某個軟件逼著裝 3.5 的普通用戶。核心內(nèi)容圍繞三件事展開——為什么在線裝不上、離線包的源從哪里來、DISM 到底該怎么敲。我會把每一步的參數(shù)含義、報錯代碼的根因、鏡像版本對不上的坑還有我自己踩過的幾次翻車經(jīng)歷都寫進(jìn)去。讀完你應(yīng)該能做到手里只有一個 Windows ISO在沒有外網(wǎng)的環(huán)境下把 .NET 3.5 穩(wěn)穩(wěn)裝上。先說一個容易混淆的概念。.NET Framework 3.5 不是一個單獨的東西它是個“疊加包”——里面包含了 2.0、3.0 和 3.5 三個世代的運(yùn)行時還有一堆 WCF、WF、LINQ 相關(guān)的程序集。Windows 10 和 Windows 11 的內(nèi)核里其實一直保留著這套運(yùn)行時的按需功能Feature on Demand簡稱 FoD文件放在系統(tǒng)鏡像的sources\sxs目錄里只是默認(rèn)不激活。所以離線安裝的本質(zhì)不是“下載安裝包”而是“告訴系統(tǒng)去本地找那堆已經(jīng)躺在鏡像里的組件把它們注冊進(jìn)系統(tǒng)”。想通這一點后面所有命令就好理解了。1.1 到底哪些軟件還在依賴它很多人以為 3.5 早就該淘汰了實際上依賴它的東西比想象中多。我整理了一下這幾年實際遇到的場景大概分這么幾類。第一類是行業(yè)專用軟件。制造業(yè)的 MES 客戶端、老版本的 SolidWorks 和 AutoCAD 插件、某些數(shù)控機(jī)床的配套上位機(jī)軟件這些軟件的開發(fā)年代集中在 2008 到 2014 年底層就是 .NET 2.0/3.5 寫的。廠商早就停止更新了但設(shè)備還在跑你就得給它把環(huán)境配齊。第二類是財務(wù)和 ERP 客戶端。不少國內(nèi)財務(wù)軟件的舊版本、報表工具、稅務(wù)申報客戶端安裝時明確檢查 .NET 3.5 是否存在缺了就直接拒絕安裝。第三類是某些開發(fā)工具和歷史項目。Visual Studio 的老版本項目、用 ASP.NET WebForms 寫的遺留系統(tǒng)、還有一些基于 WPF 3.5 的內(nèi)部工具。第四類比較隱蔽——某些驅(qū)動安裝程序、打印機(jī)工具、甚至部分游戲的啟動器會在后臺靜默依賴 3.5 的組件缺了之后表現(xiàn)為莫名其妙的崩潰日志里才看得到FileNotFoundException: System.Web。所以判斷標(biāo)準(zhǔn)很簡單只要安裝程序明確提示要 3.5或者你查事件日志看到加載mscorlib 2.0.0.0失敗那就是它。1.2 Windows 8 之后系統(tǒng)為什么默認(rèn)不裝從 Windows 8 開始微軟把 .NET 3.5 從“默認(rèn)安裝”改成了“按需功能”。原因有兩個層面。技術(shù)上的原因是體積和依賴。3.5 這套運(yùn)行時的完整文件大概幾百 MB而且它和 .NET 4.x 是并行的兩套 CLR互不替代。微軟希望新軟件都遷移到 4.x所以把 3.5 做成可選用得到再裝。分發(fā)上的原因是安全更新。默認(rèn)不啟用意味著不需要為它持續(xù)打補(bǔ)丁減少了系統(tǒng)的攻擊面。問題就出在這個“按需”的取件方式上。Windows 默認(rèn)的策略是去 Windows Update 上拉取 FoD 包。這就導(dǎo)致了兩個致命場景一是機(jī)器沒有外網(wǎng)或者被防火墻攔了 Windows Update 域名直接超時或者報錯二是企業(yè)內(nèi)網(wǎng)有 WSUS 服務(wù)器但 WSUS 沒有同步 FoD 內(nèi)容客戶端會傻乎乎地去找 WSUS 要然后拿到 0x800F0954。這兩種情況在我們實際運(yùn)維里占了絕大多數(shù)。1.3 在線安裝為什么會失敗先把在線安裝的兩種方式擺出來方便你對照自己的情況。第一種是圖形界面控制面板 → 程序和功能 → 啟用或關(guān)閉 Windows 功能 → 勾選“.NET Framework 3.5包括 .NET 2.0 和 3.0”。這個操作背后其實調(diào)用的也是 DISM只是套了個殼。第二種是命令行DISM /Online /Enable-Feature /FeatureName:NetFx3 /All。兩者失敗的原因高度一致我列個對照表你自己對號入座。報錯代碼觸發(fā)條件本質(zhì)原因0x800F0906無外網(wǎng)直連 Windows Update找不到下載源DNS 或連接超時0x800F081F指定了錯誤的本地源路徑源目錄里沒有匹配版本的 sxs 文件0x800F0954域環(huán)境走 WSUSWSUS 未同步 FoD 內(nèi)容或策略強(qiáng)制只從 WSUS 取0x800F0907組策略限制“指定可選組件安裝和組件修復(fù)的設(shè)置”被配置為禁用0x800F0922磁盤空間不足或組件存儲損壞系統(tǒng)分區(qū)預(yù)留空間不夠或 WinSxS 異??辞宄@張表后面的操作就有了方向要么給系統(tǒng)一個靠譜的本地源要么把攔路的策略改掉。2. 離線安裝的三條路線和選型邏輯離線裝 3.5 不是只有一種方法我把它歸納成三條路線。每條路線的原理、優(yōu)劣、適用場景都不一樣選錯了會在某個環(huán)節(jié)卡半天。2.1 官方源路線DISM 搭配 ISO 里的 sxs 目錄這是最正統(tǒng)的做法。你手上有和當(dāng)前系統(tǒng)版本號、語言、架構(gòu)三者完全一致的 Windows ISO掛載之后把sources\sxs目錄作為源傳給 DISM。DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /Source:D:\sources\sxs /LimitAccess參數(shù)逐個解釋/Online表示操作當(dāng)前運(yùn)行的系統(tǒng)/Enable-Feature是啟用功能/FeatureName:NetFx3指定功能名/All表示把該功能的父功能也一并啟用/Source:后面跟本地源路徑/LimitAccess是關(guān)鍵它告訴 DISM不要回頭去找 Windows Update只用本地源。這條路線最大的優(yōu)點是干凈、官方、可復(fù)現(xiàn)。缺點也明顯你必須有匹配的 ISO。這里說的匹配不只是“都是 Windows 10”而是要精確到內(nèi)部版本號和語言。用 Windows 10 21H2 的 ISO 給一臺 22H2 的機(jī)器裝很大概率報 0x800F081F。2.2 本地緩存路線從已裝好的同版本機(jī)器復(fù)制如果你手上有另一臺完全相同版本、已經(jīng)裝好 3.5 的機(jī)器可以把它C:\Windows\WinSxS里相關(guān)的組件目錄拷出來當(dāng)作源。這個方法在應(yīng)急時很好使但我不太推薦作為常規(guī)手段原因是 WinSxS 里的文件是有硬鏈接和權(quán)限保護(hù)的直接拷容易拷不全而且不同補(bǔ)丁級別的機(jī)器文件版本會有細(xì)微差異。比較穩(wěn)妥的做法是用dism /online /cleanup-image /analyzecomponentstore之類的手段確認(rèn)或者更干脆地直接在已裝好的機(jī)器上用Export-WindowsDriver的思路導(dǎo)出——不過這個操作復(fù)雜度高應(yīng)急價值大于日常價值。真要跨機(jī)器復(fù)用我更傾向下面第三條路。2.3 部署包路線獨立 CAB 文件微軟在 FoD 的 ISO 里其實單獨提供了 CAB 包命名大致是Microsoft-Windows-NetFx3-OnDemand-Package~31bf3856ad364e35~amd64~~.cab這種格式。你可以直接對 CAB 執(zhí)行安裝。DISM /Online /Add-Package /PackagePath:C:\packages\Microsoft-Windows-NetFx3-OnDemand-Package.cab這條路線適合做標(biāo)準(zhǔn)化分發(fā)——把 CAB 提取出來放進(jìn)你的軟件分發(fā)庫配合 SCCM 或者自研的部署腳本一臺臺推下去。缺點同樣是包必須和系統(tǒng)版本嚴(yán)格匹配且部分系統(tǒng)上 CAB 安裝后還需要補(bǔ)一次/Enable-Feature才能真正激活。2.4 三條路線的對比和我的選型建議維度ISO sxs 路線本機(jī)緩存路線CAB 包路線成功率高版本匹配時中高版本匹配時版本要求嚴(yán)格匹配嚴(yán)格匹配嚴(yán)格匹配可腳本化好差最好適合場景單機(jī)、現(xiàn)場裝機(jī)應(yīng)急批量部署我的推薦度首選備選批量時首選我個人的經(jīng)驗是單臺機(jī)器現(xiàn)場處理用 ISO sxs 路線最省心如果是給一個部門幾十臺機(jī)器統(tǒng)一處理就提前把 CAB 包和腳本準(zhǔn)備好走軟件分發(fā)。緩存路線只在“手上實在沒有 ISO但旁邊有一臺好機(jī)器”的極端情況下用。3. 動手前的準(zhǔn)備工作鏡像、權(quán)限、校驗?zāi)サ恫徽`砍柴工。這一步做扎實后面能省掉大量排查時間。3.1 找到匹配版本的 Windows 鏡像先確認(rèn)目標(biāo)機(jī)器的準(zhǔn)確版本。打開“運(yùn)行”輸入winver你會看到類似“版本 22H2OS 內(nèi)部版本 22621.3155”的信息。這里要抓兩個東西版本號22H2和內(nèi)部版本號22621。然后去獲取對應(yīng)的 ISO。企業(yè)環(huán)境里通常從微軟的批量許可服務(wù)中心VLSC下載或者用 Media Creation Tool 生成。個人用戶可以走微軟官網(wǎng)的下載頁面。拿到 ISO 之后右鍵“屬性”確認(rèn)真實性別用來源不明的鏡像。提示內(nèi)部版本號的前五位是關(guān)鍵。22621 和 22631 雖然是同一代 Windows 11但嚴(yán)格來說 sxs 內(nèi)容會有差異盡量找內(nèi)部版本號一致的。3.2 校驗鏡像的語言和版本一致性被忽略最多的就是語言。中文系統(tǒng)的機(jī)器配英文 ISOsxs 里的組件語言標(biāo)記對不上一樣報 0x800F081F。確認(rèn)方法ISO 里sources\sxs目錄下的文件夾名會帶語言代碼中文版通常是zh-cn英文版是en-us。另一個容易翻車的是版本類型。Windows 10 家庭版、專業(yè)版、企業(yè)版的 sxs 內(nèi)容在大部分情況下是通用的但從 LTSC 版本拿來的 ISO 給普通版本用或者反過來偶爾會出現(xiàn)組件清單對不上的情況。我的建議是盡量找同 SKU、同語言、同內(nèi)部版本的 ISO。3.3 掛載 ISO 并定位 sxs 目錄掛載很簡單雙擊 ISO 文件Windows 會自動掛載成一個虛擬光驅(qū)盤符比如D:。然后確認(rèn) sxs 目錄存在dir D:\sources\sxs正常的話你會看到一堆.cab文件還有幾個.mum清單文件。如果這個目錄不存在或者為空說明你拿到的鏡像不完整——尤其是從某些渠道拿到的“精簡版”鏡像sxs 目錄經(jīng)常被刪掉。這種情況直接換鏡像別浪費時間。另外一個技巧如果不想掛載 ISO可以用wimlib或者 DISM 從install.wim里把內(nèi)容掛出來。不過對于 3.5 這個需求掛 ISO 已經(jīng)足夠沒必要繞遠(yuǎn)路。3.4 權(quán)限與執(zhí)行環(huán)境的坑DISM 操作需要管理員權(quán)限。普通的 CMD 窗口敲下去會報“錯誤 740請求的操作需要提升”這種情況右鍵 CMD 選“以管理員身份運(yùn)行”即可。還有一個坑很多人栽過在 32 位進(jìn)程里調(diào)用 DISM。如果你是從某個安裝程序內(nèi)部觸發(fā)的或者用了一個 32 位的終端工具DISM 會去找SysWOW64下的版本可能行為不一致。穩(wěn)妥的做法是直接用系統(tǒng)自帶的cmd.exe在管理員模式下執(zhí)行。最后確認(rèn)系統(tǒng)分區(qū)至少有 3~5 GB 的可用空間。3.5 裝完之后 WinSxS 會膨脹空間不夠會直接報 0x800F0922。4. 命令行實操DISM 安裝全流程到這一步假設(shè)你已經(jīng)掛好了 ISO管理員 CMD 也開好了。下面按步驟走。4.1 標(biāo)準(zhǔn)流程與參數(shù)逐條拆解先執(zhí)行這條命令DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /Source:D:\sources\sxs /LimitAccess執(zhí)行后你會看到進(jìn)度條正常的話最后輸出操作成功完成。這里我把參數(shù)再拆細(xì)一點因為很多人復(fù)制命令時不理解為什么這么寫。/Online—— 針對正在運(yùn)行的操作系統(tǒng)。如果是在 WinPE 或者離線鏡像上操作就要改成/Image:加掛載路徑。這是兩碼事別搞混。/All—— 3.5 在功能樹里是個有父節(jié)點的拓?fù)浣Y(jié)構(gòu)/All保證父功能比如 .NET 2.0/3.0 的支撐功能一起啟用。少了它裝完之后可能某些老程序還是報錯。/Source:D:\sources\sxs—— 這里有個細(xì)節(jié)。路徑必須是sxs這一級而不是它的上級sources。DISM 會在你給的目錄里遞歸查找清單但給的層級不對會直接判失敗。/LimitAccess—— 加了這個參數(shù)DISM 就會“死心”只用本地源不會因為本地缺了某幾個文件就偷偷連網(wǎng)。在斷網(wǎng)環(huán)境下加不加都一樣但在半聯(lián)網(wǎng)環(huán)境下這個參數(shù)能保證行為可預(yù)測。4.2 用 install.wim 直接當(dāng)源的高級玩法如果你手里沒有 ISO但有一個install.wim文件比如從 WDS 或者 MDT 的部署共享里拿到的也能當(dāng)源用只是要先掛載出來。mkdir C:\wim_mount DISM /Mount-Image /ImageFile:D:\sources\install.wim /Index:1 /MountDir:C:\wim_mount /ReadOnly DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /Source:C:\wim_mount\sources\sxs /LimitAccess DISM /Unmount-Image /MountDir:C:\wim_mount /Discard這里的/Index:1要選對。一個 install.wim 里可能有家庭版、專業(yè)版、企業(yè)版多個索引你要選和目標(biāo)機(jī)器 SKU 對應(yīng)的那個??梢韵扰蹹ISM /Get-WimInfo /WimFile:D:\sources\install.wim看清單。/ReadOnly掛載是個好習(xí)慣避免誤改到鏡像。卸載時用/Discard保證不改動原 WIM。這個玩法的好處是不需要虛擬光驅(qū)適合在服務(wù)器上批處理壞處是步驟多掛載和卸載都要時間。4.3 批量部署時的腳本封裝給多臺機(jī)器處理我一般寫成這樣一段批處理放在共享目錄里推下去執(zhí)行echo off setlocal set SRC\\fileserver\deploy\win11_22h2\sources\sxs ver | findstr /i 10\. nul if %errorlevel%0 ( echo 檢測到 Windows 10/11 ) dism /online /get-featureinfo /featurename:NetFx3 | findstr /i 狀態(tài): 已啟用 nul if %errorlevel%0 ( echo NetFx3 已啟用跳過 goto :end ) dism /online /enable-feature /featurename:NetFx3 /all /source:%SRC% /limitaccess if %errorlevel% neq 0 ( echo 安裝失敗錯誤碼 %errorlevel% exit /b %errorlevel% ) echo 安裝完成 :end endlocal注意里面做了冪等檢查——先用get-featureinfo判斷是不是已經(jīng)啟用避免重復(fù)裝導(dǎo)致無謂的等待。共享路徑\\fileserver\...需要執(zhí)行賬戶有讀取權(quán)限域環(huán)境里通常用計算機(jī)賬戶或者一個有權(quán)限的服務(wù)賬戶跑。腳本里我沒加語言判斷和版本校驗因為實際部署時這些應(yīng)該在前置環(huán)節(jié)就保證。如果你要做得更嚴(yán)可以在腳本開頭用wmic os get version比對內(nèi)部版本號。4.4 安裝完成后的驗證方法裝完不要只看 DISM 輸出“操作成功完成”就完事要實際驗證。第一層驗證查功能狀態(tài)DISM /Online /Get-FeatureInfo /FeatureName:NetFx3輸出里“狀態(tài)”應(yīng)該是“已啟用”。第二層驗證查注冊表reg query HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5 /v InstallInstall值應(yīng)該是0x1。第三層驗證實際跑一下老程序。最直接的辦法是打開 PowerShell 之外的 CMD輸入%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\csc.exe如果沒報“找不到文件”而是彈出版本信息說明 2.0 的編譯器已經(jīng)在位了。三層都過了才算真正裝好。5. 組策略與 WSUS 環(huán)境下的特殊處理這一節(jié)專門給企業(yè)域環(huán)境。前面說過域機(jī)器報 0x800F0954 的概率極高根因就在組策略。5.1 0x800F0954 的根因組策略里有這么一條路徑計算機(jī)配置 → 管理模板 → 系統(tǒng) → 指定可選組件安裝和組件修復(fù)的設(shè)置英文路徑是Computer Configuration → Administrative Templates → System → Specify settings for optional component installation and component repair如果這條策略被設(shè)成“已啟用”并且勾了“僅從 Windows Server Update Services (WSUS) 下載修復(fù)內(nèi)容”那客戶端的 DISM 就會強(qiáng)制走 WSUS。WSUS 默認(rèn)不同步 FoD 的Microsoft-Windows-NetFx3-OnDemand-Package這類包于是客戶端請求不到報 0x800F0954。還有一種情況是策略沒啟用這項但環(huán)境里有 WSUS 且客戶端已經(jīng)通過wuauclt注冊過DISM 仍然會優(yōu)先問 WSUS。5.2 臨時修改策略的正確姿勢注意我說的是“臨時”。生產(chǎn)環(huán)境中不該為了裝一個組件就把全局策略改掉。正確的做法是在目標(biāo)機(jī)器上臨時加一條覆蓋性注冊表裝完刪掉。策略對應(yīng)的注冊表鍵是HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU相關(guān)值包括UseWUServer。把這個值臨時設(shè)為0然后重啟 Windows Update 服務(wù)再執(zhí)行 DISM 命令裝完把值改回去。具體操作reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer /t REG_DWORD /d 0 /f net stop wuauserv net start wuauserv裝完恢復(fù)reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer /t REG_DWORD /d 1 /f net stop wuauserv net start wuauserv注意這個方法在大部分域環(huán)境有效但如果你的組策略是每 90 分鐘刷新一次臨時改的注冊表可能在你操作期間被刷回。穩(wěn)妥做法是操作間隔盡量短或者和域管理員協(xié)調(diào)在維護(hù)窗口做。5.3 企業(yè)域環(huán)境下的取舍從長期來看域環(huán)境更優(yōu)雅的方案有兩個。一是讓 WSUS 管理員啟用“功能和語言包”的同步。在 WSUS 控制臺的“選項 → 產(chǎn)品和分類”里勾上“Windows 10, version 1903 and later”以及對應(yīng)的“功能和語言包”分類FoD 內(nèi)容就會同步到 WSUS客戶端走正常通道即可裝 3.5。這個方案一次配置長期受益代價是 WSUS 存儲會漲不少。二是走“旁加載”路線。把 sxs 目錄或者 CAB 包放到內(nèi)網(wǎng)文件服務(wù)器用組策略登錄腳本統(tǒng)一檢測安裝。這就是我前面 4.3 節(jié)的腳本思路只是把它掛到組策略的計算機(jī)啟動腳本上。我個人的取舍機(jī)器數(shù)量少10 臺以內(nèi)現(xiàn)場手動處理幾十臺以上推動 WSUS 同步上百臺上腳本分發(fā)。6. 常見報錯速查與排查實錄這一節(jié)是這篇文章的干貨分量最重的部分。我把這幾年實際處理過的典型問題整理出來。6.1 錯誤代碼對照與定位路徑報錯代碼優(yōu)先排查方向快速修復(fù)動作0x800F0906網(wǎng)絡(luò)、Windows Update 服務(wù)加/LimitAccess和本地源0x800F081F源路徑、鏡像版本、語言匹配換匹配的 ISO確認(rèn) sxs 有內(nèi)容0x800F0954WSUS、組策略臨時改UseWUServer0x800F0907組策略“指定可選組件安裝”設(shè)置檢查策略是否配置為禁用0x800F0922磁盤空間、組件存儲清理 WinSxS或擴(kuò)容0x80073712組件存儲損壞先跑DISM /Online /Cleanup-Image /RestoreHealth0x80070005權(quán)限不足用管理員 CMD6.2 幾個真實案例的排查過程案例一Windows 11 專業(yè)版 Insider Preview 29667.1000 無法安裝 .NET Framework 3.5 SP1這個場景挺典型。用戶裝的是 Insider Preview 的某個預(yù)發(fā)布版本機(jī)器聯(lián)網(wǎng)但拿不到匹配的 FoD 包。原因有兩個一是 Insider 版本的 FoD 內(nèi)容在 Windows Update 上分發(fā)是滯后的很多時候預(yù)覽版剛發(fā)布時對應(yīng)的按需包還沒上線二是用戶手上沒有和 29667 這個內(nèi)部版本匹配的 ISO。我的處理思路是先確認(rèn)是不是版本匹配問題用winver看內(nèi)部版本再去 Windows Update 上跑一次完整更新如果還是不行說明 FoD 通道沒放內(nèi)容這時候要么退回穩(wěn)定版要么用上一代穩(wěn)定版的 sxs 試著裝成功概率一般屬于“碰運(yùn)氣”。結(jié)論是Insider Preview 的機(jī)器不建議作為依賴 3.5 的生產(chǎn)設(shè)備這個坑先天存在。案例二x86 老機(jī)器裝 .NET 2.0~3.5 全量包有臺 Windows 10 1909 的 32 位機(jī)器客戶要求 2.0、3.0、3.5 全裝。注意這里一個細(xì)節(jié)Windows 10/11 上的 NetFx3 功能其實同時覆蓋了 2.0、3.0、3.5 三個世代不需要單獨裝 2.0。客戶以為要裝三個包實際一條命令就夠了。另外 x86 機(jī)器的 sxs 目錄和 x64 不同鏡像必須是對應(yīng)架構(gòu)的。用 64 位 ISO 的 sxs 給 32 位機(jī)器裝DISM 會報找不到匹配的包。案例三裝完 NetFx3 但程序仍報錯一個客戶的 ASP.NET 老系統(tǒng)裝完 3.5 之后IIS 里跑起來還是 500。排查發(fā)現(xiàn)是IIS 的應(yīng)用程序池沒有配置為 .NET CLR v2.0。3.5 的運(yùn)行時在 IIS 里對應(yīng)的是 v2.0 的應(yīng)用池默認(rèn)新版本 IIS 都建 v4.0 的池需要手動改。這個坑很多人遇到因為它不屬于“安裝”問題而是“配置”問題。6.3 一套可復(fù)用的排查思路我總結(jié)成四步遇到任何報錯按這個順序過。第一步看錯誤碼對照 6.1 的表定位大類。第二步確認(rèn)源的三要素版本、語言、架構(gòu)是否和目標(biāo)機(jī)器一致。三項里任意一項不對先換源再說。第三步檢查環(huán)境干擾是不是域機(jī)器、是不是有 WSUS、是不是有組策略限制、磁盤空間夠不夠。第四步如果前面都對還是不行跑組件存儲修復(fù)DISM /Online /Cleanup-Image /RestoreHealth sfc /scannow然后再重試安裝。實操心得我遇到過一次 0x800F081F所有人都說是鏡像版本問題換個 ISO 還是報。最后發(fā)現(xiàn)是sxs目錄在拷貝到本地磁盤時被某個殺毒軟件攔截了部分.cab文件。所以如果你的源是從共享盤或者移動硬盤拷過來的用dir /s數(shù)一下文件數(shù)量和原始 ISO 里對比一下。7. 幾個容易被忽略的細(xì)節(jié)和我的實操心得前面講了主線流程這一節(jié)說說那些“文檔里不寫、但真正干活時會遇到”的東西。7.1 語言包和系統(tǒng)區(qū)域的隱性影響有一類特別隱晦的問題系統(tǒng)語言是中文ISO 也是中文但 sxs 裝不進(jìn)去。最后查出來是系統(tǒng)的區(qū)域設(shè)置被改成了別的地區(qū)同時“非 Unicode 程序的語言”被改成了英文。這種情況下 DISM 會認(rèn)為語言環(huán)境不匹配。處理方式控制面板 → 區(qū)域 → 管理 → 非 Unicode 程序的語言改回中文簡體中國重啟后再裝。這個坑我遇到兩次每次都要找半天。7.2 關(guān)于“精簡版系統(tǒng)”的現(xiàn)實提醒市面上流傳的一些“優(yōu)化版”“純凈版”Windows 鏡像為了壓縮體積會把sxs目錄、WinSxS緩存甚至整個 FoD 組件刪掉。這種系統(tǒng)上你無論怎么操作都裝不上 3.5因為源在系統(tǒng)內(nèi)部就已經(jīng)不存在了。判斷方法DISM /Online /Get-FeatureInfo /FeatureName:NetFx3如果狀態(tài)顯示“已禁用”但顯示“刪除狀態(tài)已刪除”那就是被移除了。這種情況即使你指定外部源也可能失敗因為缺少的是系統(tǒng)內(nèi)部的清單。遇到這種機(jī)器我的建議是不要試圖搶救直接重裝一個完整版系統(tǒng)。浪費時間不如換盤。7.3 ARM64 和特殊架構(gòu)的處理Windows on ARM 的設(shè)備比如某些驍龍本裝 3.5 時sxs 目錄的架構(gòu)是arm64。用 x64 的 ISO 裝不了。同時部分 x86 應(yīng)用在 ARM64 的 Windows 上需要 x86 的模擬層支持2.0/3.5 的運(yùn)行時也需要對應(yīng)架構(gòu)的版本。這類設(shè)備目前在企業(yè)里不多但如果在處理先確認(rèn)PROCESSOR_ARCHITECTURE環(huán)境變量的值echo %PROCESSOR_ARCHITECTURE%返回ARM64就一定要找 ARM64 的 ISO。7.4 裝完之后別急著走這幾件事順手做掉第一重啟一次。雖然 DISM 不強(qiáng)制要求重啟但 3.5 的部分組件注冊在下次啟動時才真正生效。我遇到過一次不重啟導(dǎo)致 CAD 插件加載失敗重啟后就好了。第二檢查 Windows Update 有沒有把 3.5 的安全補(bǔ)丁帶上。裝完 NetFx3 之后系統(tǒng)會多出幾個針對 2.0/3.5 的更新項如果機(jī)器能聯(lián)網(wǎng)讓它自己打完更穩(wěn)妥。第三如果這臺機(jī)器要做備份或者克隆現(xiàn)在就是做鏡像的最佳時機(jī)。裝好 3.5 的狀態(tài)是很多老軟件的“基線環(huán)境”克隆一份后面遇到新機(jī)器直接還原比每次重裝省事太多。第四記錄下你用的 ISO 版本號和文件名。半年后你在另一臺機(jī)器上遇到同樣的問題翻出這個記錄直接復(fù)用不用再摸索一遍。我在團(tuán)隊里維護(hù)了一個小表格記錄每臺裝過 3.5 的機(jī)器對應(yīng)哪個 ISO長期下來省了很多重復(fù)勞動。最后分享一個我自己常用的應(yīng)急思路。如果現(xiàn)場實在找不到任何匹配的 ISO而機(jī)器又不是完全斷網(wǎng)可以試試先臨時允許 Windows Update 幾分鐘讓系統(tǒng)自己把 FoD 拉下來裝完再斷開。這個方法不違規(guī)也不依賴外部工具代價是需要網(wǎng)絡(luò)窗口適合作為最后的兜底方案。但如果是嚴(yán)格隔離的內(nèi)網(wǎng)機(jī)器還是老老實實準(zhǔn)備 ISO 和 CAB 包把源掌握在自己手里這才是最可控的做法。