首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

COM 呼叫 WCF 服務實戰 (四):服務專用字串與設定檔突破 64K 訊息限制

     編輯:關於.NET

系列第四篇解決實戰難題:VB6/VBA/VBScript 透過服務專用字串呼叫 WCF 時,回應訊息超過 wsHttpBinding 預設 MaxReceivedMessageSize=65536 導致失敗。關鍵在於 **如何讓非 .NET 宿主 (wscript.exe, winword.exe, excel.exe, 自製 VB6 EXE) 載入自訂繫結設定檔**。本文提供完整設定檔命名規則、放置路徑、以及僅支援「類型化契約」的限制說明。

問題背景

前三篇均使用預設 wsHttpBinding,訊息體積小無問題。實際專案中 WCF 回傳大量資料 (如報表、基64 編碼圖片) 極易超過 64 KB。需調整:

  • maxReceivedMessageSize
  • maxBufferPoolSize
  • readerQuotas.maxStringContentLength

但在 COM 宿主環境無 app.config 機制,**如何注入設定?**

核心解法:宿主同名 .config 檔案

經驗證,COM 宿主載入 WCF 通道時會探測 **宿主執行檔同目錄下、同檔名 + .config** 的設定檔:

注意:修改 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. 部署步驟

  1. 將 wscript.exe.config 複製至 C:\Windows\System32\ (需管理員)
  2. 確認服務端 Web.config 已調大繫結參數
  3. 雙擊執行 .vbs,彈出訊息框顯示完整 64K+ 回應 — **成功!**

常見坑與對策

宿主類型宿主執行檔設定檔名稱放置路徑
VBScript (.vbs)wscript.exe (預設) / cscript.exewscript.exe.config%SystemRoot%\System32\
VBA (Word)WINWORD.EXEWINWORD.EXE.configWord 安裝目錄 (如 C:\Program Files\Microsoft Office\Office16)
VBA (Excel)EXCEL.EXEEXCEL.EXE.configExcel 安裝目錄
VB6 編譯 EXEYourApp.exeYourApp.exe.configEXE 同目錄
現象原因解決
設定檔不生效檔名大小寫錯誤、放置路徑錯誤、宿主非預期進程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 訊息天花板。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved