一切只起因我想試試WCF net.tcp,卻遇上近年來數一數二的刁鑽茶包,纏鬥超過一天…
故事從前幾天寫的.NET Remoting、WCF、Web API、Socket評估文說起,結論指出當Client/Server都是.NET,WCF仍是極出色的選項,尤其使用TCP管道配合二進位格式傳輸,效能直追Socket,雖然它的設定磨人,同事與我決定再給它一次機會,研究WCF應用在專案的可能性。
最早WCF要跑TCP得自己寫服務或獨立EXE,IIS7起推出了WAS(Windows Process Activation Service),支援TCP、Named Pipe、MSMQ這些非HTTP/HTTPS協定,WCF一律寫成網站,透過設定即可提供TCP、Named Pipe、MSMQ、HTTP多種連線方式,不必為不同傳輸方式多寫半行程式,應是使用WCF最方便的做法。
使用WAS的第一步,是在「開啟或關閉Windows功能」新増「WCF服務/TCP啟用」(TCP Activation)選項:(我的作業系統是Windows 8.1)
結果…
更!WCF不但設定難搞,還安裝過程都要刁我一下是怎樣?
爬文發現安裝Windows功能遇上0x800F0922錯誤常起因於系統檔案毁損,有兩種解決方式:
改由Windows安裝媒體(原始安裝光碟)或Windows Update安裝
參考
找出要安裝功能的完整名稱(WCF-TCP-Activation45)
Dism /online /get-features > e:\Features.txt
使用安裝光碟(D槽)
Dism /online /enable-feature /featurename:WCF-TCP-Activation45 /All /Source:D:\sources\sxs /LimitAccess
或由Windows Update下載安裝
Dism /online /enable-feature /featurename:WCF-TCP-Activation45 /All
結果:安裝失敗,一樣傳回:
錯誤: 0x800f0922
DISM 失敗。未執行任何操作。
如需詳細資訊,請檢閱記錄檔。
在 C:\Windows\Logs\DISM\dism.log 中可找到 DISM 記錄檔修復系統檔案
就是昨天提到的Windows系統更新失敗之初步排除步驟,修復完畢仍無法解決問題。
也有人提到安裝失敗可能跟防毒軟體有關,找了同事的Windows 8.1(Windows版本、防毒軟體等環境相似)測試安裝「TCP啟用」功能,像風一般瞬間安裝完成!(跌坐在地)啊啊啊啊,為什麼只有我被詛咒?orz
反覆試了好幾次,重開機數回,在Windows\Logs\CBS\CBS.log找到類似下方的失敗記錄:
(0) LockComponentPath (10): flags: 0 comp: {l:16 b:fa7fd5a65ce0d0011300000034264c2a} pathid: {l:16 b:fa7fd5a65ce0d0011400000034264c2a} path: [l:230{115}]"\SystemRoot\WinSxS\amd64_netfx-wcf-tcpactivation-registration_31bf3856ad364e35_4.0.9600.16384_none_6ef4da88718e1ebe" pid: 2634 starttime: 130851077419943182 (0x01d0e05c9417c50e)
2015-08-27 08:09:33, Error CSI 00000001 (F) Logged @2015/8/27:00:09:33.447 : [ml:84{42},l:82{41}]"installing service NetTcpActivator online"
[gle=0x80004005]
2015-08-27 08:09:33, Error CSI 00000002 (F) Logged @2015/8/27:00:09:33.449 : [ml:58{29},l:56{28}]"CreateService failed (15100)"
[gle=0x80004005]
2015-08-27 08:09:33, Error CSI 00000003@2015/8/27:00:09:33.449 (F) CMIADAPTER: Inner Error Message from AI HRESULT = HRESULT_FROM_WIN32(15100)
[
[18]"\u8cc7\u6e90\u8f09\u5165\u5668\u627e\u4e0d\u5230 MUI \u6a94\u6848\u3002
]
[gle=0x80004005]
2015-08-27 08:09:33, Error CSI 00000004@2015/8/27:00:09:33.450 (F) CMIADAPTER: AI failed. HRESULT = HRESULT_FROM_WIN32(15100)
可以確定問題出在無法安裝amd64_netfx-wcf-tcpactivation-registration,而錯誤訊息\u8cc7\u6e90\u8f09\u5165\u5668\u627e\u4e0d\u5230 MUI \u6a94\u6848\u3002轉成中文是「資源載入器找不到 MUI 檔案。/ The resource loader failed to find MUI file.」,已做過DISM修復,SFC掃瞄沒有任何錯誤,為什麼還缺檔?茫然無頭緒之際,「重新安裝Windows吧」的不好念頭悄悄在腦海飄過… 不行!重灌是弱者魯蛇的行為,身為茶包射手,拔刀才戰兩回就想著要不要投降成何體統,收拾書包回家冷靜冷靜。
第二天晨跑時繼續琢磨,頓時靈光一現:「笨!既然找不到MUI檔案,用Process Monitor查查缺什麼檔補上不就好了?」。回到公司再戰,開了Process Monitor側錄,卻沒發現任何找不到檔案的記錄。我不放棄,在可以正常安裝的Windows 8.1筆電也側錄一份Process Monitor記錄做比對,在數萬行記錄大海找尋可疑差異。
Process Monitor記錄一秒就好幾百筆,此時CBS.log中 2015/8/27:00:09:33.449 這種精確度到毫秒的資訊格外珍貴,鎖定 installing service NetTcpActivator online 到 CreateService failed (15100) 期間安裝程式的存取記錄,發現一項疑點:
有個 HKEY_USERS\.DEFAULT\Software\Classes\Local Settings\MuiCache\6df\474A91C\@%systemroot\\Microsoft.NET\\Framework64\\v4.0.30319\\ServiceModelInstallRC.dll,-8199 Registry 找不到,「MuiCache」讓人精神一振,該不會錯誤訊息說的找不到MUI檔案其實是讀不到MUI相關Registry?
我還發現不同Windows 8.1版本這部分結構也不同,MuiCache\*\474A91C下有很多服務、程式相關的中文字串,筆電是Windows 8.1專業版,就沒有"@%systemroot\\Microsoft.NET\\Framework64\\v4.0.30319\\ServiceModelInstallRC.dll,-8199"這一項,最後在同事的Windows 8.1企業版倒是有找到它。請同事匯出Registry,自己補成reg檔案(每台機器的Registry有別,例如6df這個數字,同事跟我的機器就不同,無法直接套用要手工調):
Windows Registry Editor Version 5.00
[HKEY_USERS\.DEFAULT\Software\Classes\Local Settings\MuiCache\6df\474A91C]
"@%systemroot\\Microsoft.NET\\Framework64\\v4.0.30319\\ServiceModelInstallRC.dll,-8199"="Net.Tcp Listener Adapter"
"@%systemroot%\\Microsoft.NET\\Framework64\\v4.0.30319\\ServiceModelInstallRC.dll,-8198"="透過 net.tcp 通訊協定收到啟用要求,並將它們傳送至 Windows Process Activation Service。"
補上Registry,懷著緊張的心情再試一次… 媽啊!像是打出全壘打般,我恨不得在辦公室繞場一圈。
我 成 功 裝 好 TCP啟動 了!
從沒想過裝好一項Windows功能會讓我如此激動… 補聲暗!