首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ ISAPI 擴展開發入門:從專案建立到 Hello Web 完整實戰

     編輯:VC 教學

前言

ISAPI (Internet Server API) 是 IIS 早期高效能擴展技術:**DLL 常駐記憶體、無進程建立開銷**、比 CGI 快數十倍。雖然現代已轉向 ASP.NET Core / Node.js,但理解 ISAPI 有助於維護舊系統、掌握 **原生 HTTP 伺服器擴展模型**。本文基於 VC6 MFC ISAPI Wizard 完整演示。

ISAPI vs CGI 核心差異

維度CGIISAPI
進程模型每請求建立新進程DLL 載入 IIS 進程,常駐
效能低 (進程建立/銷毀、環境變數傳遞)高 (執行緒池、記憶體共享)
狀態保持困難 (需外部儲存)容易 (全域/靜態變數、記憶體快取)
開發語言任意 (Perl, C, VB...)C/C++ (需編譯為 DLL)
除錯難度低 (獨立進程)高 (需附加至 IIS 進程)

MFC ISAPI 專案建立步驟 (VC6)

  1. File → New → Projects → **ISAPI Extension Wizard** → 專案名 `HelloWeb`
  2. Wizard 選項:MFC 動態連結 (預設) → Finish
  3. 產生類別:`CHelloWebExtension : public CHttpServer`

核心架構:Parse Map + Command Handler

1. Parse Map (URL 路由表)


BEGIN_PARSE_MAP(CHelloWebExtension, CHttpServer)
    ON_PARSE_COMMAND(Default, CHelloWebExtension, ITS_EMPTY)
    // 自訂命令範例:
    // ON_PARSE_COMMAND(ShowTime, CHelloWebExtension, ITS_EMPTY)
    // ON_PARSE_COMMAND_PARAMS(Echo, CHelloWebExtension, ITS_STRING)
    DEFAULT_PARSE_COMMAND(Default, CHelloWebExtension)
END_PARSE_MAP(CHelloWebExtension)
  • `ON_PARSE_COMMAND(cmd, class, type)`:匹配 URL `.../HelloWeb.dll?cmd`
  • `ON_PARSE_COMMAND_PARAMS(cmd, class, type)`:匹配 `.../HelloWeb.dll?cmd+params`
  • `DEFAULT_PARSE_COMMAND`:無命令/匹配失敗時的回退

2. Command Handler (業務邏輯)


void CHelloWebExtension::Default(CHttpServerContext* pCtxt) {
    StartContent(pCtxt);           // 寫入 
    WriteTitle(pCtxt, _T("Hello Web"));
    *pCtxt << _T("Hello from ISAPI Extension!");
    EndContent(pCtxt);             // 寫入 
}

void CHelloWebExtension::ShowTime(CHttpServerContext* pCtxt) {
    StartContent(pCtxt);
    WriteTitle(pCtxt, _T("Server Time"));
    CTime t = CTime::GetCurrentTime();
    *pCtxt << t.Format(_T("%Y-%m-%d %H:%M:%S"));
    EndContent(pCtxt);
}

除錯環境配置 (關鍵難點)

  1. 專案設定 → Debug → Executable for debug session:`C:\WINNT\System32\inetsrv\inetinfo.exe` (IIS 4/5) 或 `w3wp.exe` (IIS 6+)
  2. Program arguments:`-e w3svc` (以控制台模式啟動 WWW 服務)
  3. Link → Output file name:放入虛擬目錄實體路徑,如 `C:\Inetpub\Scripts\HelloWeb.dll`
  4. **權限設定**:控制台 → 管理工具 → 本地安全性原則 → 本地原則 → 用戶權利指派 →
    • 「作為作業系統一部分」加入開發帳號
    • 「產生安全稽核」加入開發帳號
    → 重新登入
  5. 停用 IIS 服務 (服務管理員),改由除錯器啟動 `inetinfo.exe`

測試驗證

  1. 按 F5 啟動除錯,IIS 在控制台視窗運行
  2. 瀏覽器訪問:`https://localhost/HelloWeb.dll?` (尾部問號觸發 Default)
  3. 預期輸出:`Hello from ISAPI Extension!`
  4. 訪問 `https://localhost/HelloWeb.dll?ShowTime` → 顯示伺服器時間

常見錯誤與對策

  • 專案設定 → General → Use MFC in a **Static Library**
  • 或部署 `mfc42.dll` 等
  • IIS 重啟 / 觸發 `inetinfo.exe` 重載
  • 專案設定 → Link → Generate Debug Info
  • ISAPI 多執行緒並發,**嚴禁非同步安全的全域變數**
  • 用 `CCriticalSection` 保護共享資料
  • `*pCtxt << "Content-Type: text/html; charset=gb2312\r\n\r\n";`
  • 或專案設 Unicode + UTF-8 輸出
  • 錯誤原因對策
    Server Error 500: Specified module not found動態連結 MFC 但目標機無 MFC DLL
    斷點不命中DLL 未重新載入 / PDB 不匹配
    存取違規執行緒安全 / 全域資料競爭
    中文亂碼未設定 Content-Type charset

    進階:ISAPI Filter (過濾器)

    • 繼承 `CHttpFilter`,覆寫 `OnUrlMap`、`OnPreprocHeaders`、`OnSendRawData` 等
    • 用途:URL 重寫、認證攔截、壓縮、日誌、防火牆
    • 註冊:IIS 管理單元 → 屬性 → ISAPI Filters → Add

    現代替代與遷移建議

    • ASP.NET Core:跨平台、高效能、現代生態、Kestrel/IIS 整合
    • CGI / FastCGI:PHP、Python、Go 等非 Windows 棧
    • Http.sys Kernel Mode Driver:Windows 核心級 HTTP 堆疊,`HttpCreateServerSession` 等 API,比 ISAPI 更底層、更快

    結語

    ISAPI 是 **「DLL 常駐、執行緒服務、Parse Map 路由」** 的經典模式,深刻影響了後世所有原生 HTTP 伺服器框架。維護舊專案時,請記住:**除錯附加 inetinfo.exe、靜態連結 MFC、執行緒安全第一**。新專案請毫不猶豫選擇 ASP.NET Core 或跨平台替代方案——**致敬經典,但不停留在過去**。

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