一切只起因我想試試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錯誤常起因於系統檔案毁損,有兩種解決方式:

  1. 改由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 記錄檔
  2. 修復系統檔案
    就是昨天提到的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功能會讓我如此激動… 補聲暗!


Comments

# by 小說

靠~太曲折了,我決定用 web api

# by ALEX

理論上這兩個registry 項目,應該是在安裝WCF TCP啟用時 Windows 會自動新增才對啊 好奇 是什麼原因 Windows 沒有幫忙新增 導致後續的錯誤

# by Michael Yang

我在Windows 2012 R2上,如果先裝.net 4.6.1,再裝WCF服務/TCP啟用也會發生這個問題。除了改registry外,再另外裝一個.net 4.6.1的繁中語言套件後,也可以解決。

# by Jeffrey

to Michael Yang, 感謝你的經驗補充。

Post a comment