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

COM 組件自動註冊與卸載機制全解析

     編輯:VC 教學

一、進程內組件 — 利用 RegSvr32.exe

DLL 類組件透過匯出標準函數實現註冊:

  • 註冊:RegSvr32.exe D:\com.dll
    內部呼叫 DllRegisterServer
  • 反註冊:RegSvr32.exe /u D:\com.dll
    內部呼叫 DllUnregisterServer

開發者需在 DLL 中實作這兩個匯出函數,執行登錄寫入/刪除 (CLSID、ProgID、TypeLib、介面代理等)。

二、進程外組件 (EXE) — 命令列參數自註冊

EXE 無法被 RegSvr32 載入,COM 規範要求支援兩個命令列參數:

  • MyServer.exe /RegServer — 註冊
  • MyServer.exe /UnregServer — 反註冊

啟動時解析命令列,執行相應註冊邏輯後立即退出。

三、組件自動卸載 — CoFreeUnusedLibraries

COM 提供 CoFreeUnusedLibraries() (舊版為 CoFreeAllLibraries) 實現延遲卸載:

  1. 應用程式定期呼叫 (如訊息迴圈閒置時、計時器觸發)
  2. COM 遍歷當前進程載入的所有 DLL 組件
  3. 檢查兩個條件 **同時滿足**:
    • 組件內物件計數為 0 (DllCanUnloadNow 回傳 S_OK)
    • 類別工廠鎖定計數為 0 (IClassFactory::LockServer(FALSE) 釋放所有鎖)
  4. 條件成立 → 呼叫 FreeLibrary 卸載 DLL

關鍵實作要點

函數/介面職責實作提示
DllCanUnloadNow回傳 S_OK 表示可卸載檢查全域物件計數 g_cObj == 0 && g_cLock == 0
IClassFactory::LockServer增加/減少鎖定計數InterlockedIncrement/Decrement 保護 g_cLock
物件建構/解構維護 g_cObj建構時 ++,解構時 --,使用 Interlocked 操作

常見誤區

  • ❌ 以為 CoFreeUnusedLibraries 會立即強制卸載 → 實為 **輪詢檢查**,需滿足條件
  • ❌ 忘記在 LockServer(TRUE) 時增加鎖計數 → 導致過早卸載,造成崩潰
  • ❌ 進程外 EXE 組件嘗試用 DllRegisterServer → EXE 應實作 /RegServer 命令列

最佳實踐建議

  1. 在應用程式訊息迴圈中定期呼叫 CoFreeUnusedLibraries() (如每 5 分鐘)
  2. 使用 ATL 專案自動生成的模組類 (CComModule/CAtlDllModuleT) 已內建完整計數與鎖邏輯
  3. 註冊邏輯盡量使用 ATL::CComModule::RegisterServer / UnregisterServer,減少手寫登錄操作錯誤
  4. 安裝程式建議直接呼叫 RegSvr32 /s 或 MyServer.exe /RegServer 靜默註冊
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved