| 宿主類型 | 宿主執行檔 | 設定檔名稱 | 放置路徑 |
| VBScript (.vbs) | wscript.exe (預設) / cscript.exe | wscript.exe.config | %SystemRoot%\System32\ |
| VBA (Word) | WINWORD.EXE | WINWORD.EXE.config | Word 安裝目錄 (如 C:\Program Files\Microsoft Office\Office16) |
| VBA (Excel) | EXCEL.EXE | EXCEL.EXE.config | Excel 安裝目錄 |
| VB6 編譯 EXE | YourApp.exe | YourApp.exe.config | EXE 同目錄 |
注意:修改 System32 下檔案需管理員權限;生產環境建議改用 cscript.exe 指定自有腳本宿主副本以避免污染系統檔案。
完整設定檔範例:客戶端與服務端同步調大
服務端 Web.config 關鍵片段
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ZXG"
maxReceivedMessageSize="6553600"
maxBufferPoolSize="52428800">
<readerQuotas maxStringContentLength="819200" ... />
<security mode="Message">...</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WCFServiceMoniker.Service1" ...>
<endpoint binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ZXG"
contract="WCFServiceMoniker.IService1" />
</service>
</services>
客戶端設定檔 (wscript.exe.config 等)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1"
maxReceivedMessageSize="655360"
maxBufferPoolSize="5242880">
<readerQuotas maxStringContentLength="819200" ... />
<security mode="Message">...</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/WCFServiceMoniker/Service1.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1"
contract="IService1"
name="WSHttpBinding_IService1">
<identity><dns value="localhost" /></identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
關鍵限制:僅支援「類型化契約」
經測試,**MEX 契約與 WSDL 契約無法透過設定檔指定繫結設定**。原因在於服務專用字串語法差異:
- 類型化專用字串:
binding=wsHttpBinding, bindingConfiguration=WSHttpBinding_IService1 — **繫結名稱與設定檔對應**
- MEX/WSDL 專用字串:
binding=WSHttpBinding_IService1 — **繫結名稱寫死在專用字串中**,無法外部注入設定
**對策**:必須先用 svcutil 產生強型別 Proxy 組件,註冊 COM 可見 (Regasm /t /codebase),再使用類型化專用字串調用。
端到端驗證範例:VBScript 呼叫大訊息服務
1. 服務端回傳超大字串
public string SayHello(string yourwords)
{
return string.Format("Hello World! You entered: {0}{1}",
yourwords, new string('A', 65536)); // 64K 'A' 字元
}
2. 客戶端 Proxy 組件 (Client.dll) — 同前三篇,無需修改
介面 IService1、實作 Service1Client、強名稱簽章、GAC 安裝、Regasm 註冊。
3. VBScript 調用代碼 (CallWCFService_TypedContract.vbs)
' 類型化專用字串,指定 bindingConfiguration
monikerString = "service:address='https://localhost/WCFServiceMoniker/Service1.svc'"
monikerString = monikerString + ", binding=wsHttpBinding, bindingConfiguration=WSHttpBinding_IService1"
monikerString = monikerString + ", contract={4FBDA94E-8B89-32EC-BC28-2A0A5E9B7C74}"
Set serviceMoniker = GetObject(monikerString)
MsgBox serviceMoniker.SayHello("I am LazyBee," & vbCrLf)
Set serviceMoniker = Nothing
4. 部署步驟
- 將
wscript.exe.config 複製至 C:\Windows\System32\ (需管理員)
- 確認服務端
Web.config 已調大繫結參數
- 雙擊執行 .vbs,彈出訊息框顯示完整 64K+ 回應 — **成功!**
常見坑與對策
| 現象 | 原因 | 解決 |
| 設定檔不生效 | 檔名大小寫錯誤、放置路徑錯誤、宿主非預期進程 | ProcMon 監控 CreateFile 確認實際讀取路徑 |
| Excel/VBA 讀不到設定 | Office 可能以 Click-to-Run 隔離執行,EXE 路徑非傳統安裝目錄 | 用 Application.Path 取得實際 EXE 目錄,放置同名 .config |
| MaxReceivedMessageSize 仍報錯 | 服務端與客戶端**雙方**皆需調大;readerQuotas 同步調整 | 對照雙方設定檔,確保數值一致且足夠大 |
| MEX/WSDL 專用字串想用設定檔 | 架構限制,繫結名稱硬編碼在專用字串 | 改用類型化契約 (產生 Proxy 組件) |
總結
- COM 宿主載入 WCF 設定檔規則:**宿主 EXE 同目錄 + 同名 .config**
- VBScript 宿主為
wscript.exe,設定檔置 System32
- VBA 宿主為
WINWORD.EXE/EXCEL.EXE,設定檔置 Office 安裝目錄
- VB6 EXE 宿主為自有 EXE,設定檔置同目錄
- **僅類型化契約支援
bindingConfiguration 參數**,MEX/WSDL 無法使用外部設定檔繫結設定
- 服務端與客戶端繫結參數 (
maxReceivedMessageSize、readerQuotas) 必須同步調大
掌握此機制,即可讓傳統 COM 應用無縫呼叫高負載 WCF 服務,打破 64K 訊息天花板。
- 上一篇文章: CLR 深度解析:Silverlight 2 CoreCLR 架構、安全模型與跨平台實現
- 下一篇文章: COM 呼叫 WCF 服務實戰 (三):WSDL 契約動態調用無需註冊類型
Copyright ©
程式碼之家 All Rights Reserved