透過 COM 技術與 IE 物件模型互動,可實現網頁記錄、內容過濾/翻譯、表單自動填寫等功能。本文系統解析三大核心技術:IE 實例枚舉、Browser Helper Object (BHO)、HTML DOM 操作。
IShellWindowsSHDocVw::IShellWindowsPtr spShellWindows;
spShellWindows.CreateInstance(__uuidof(SHDocVw::ShellWindows));
long nCount = spShellWindows->GetCount();
for (long i = 0; i < nCount; ++i) {
IDispatchPtr spDisp = spShellWindows->Item(_variant_t(i, VT_I4));
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp); // QueryInterface
if (!spBrowser) continue; // 非 IE (如總管)
// 取得文件物件
MSHTML::IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());
// 例:取得標題
_bstr_t title = spDoc->GetTitle();
}
應用:批量儲存所有開啟網頁、監控瀏覽歷程。
IE 啟動時讀取:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{Your-CLSID}
每個 CLSID 需為子鍵(非數值),IE 以 CoCreateInstance 建立實例。
IObjectWithSite::SetSite(IUnknown* punkSite):IE 傳遞自身 IUnknown,由此 QueryInterface 取得 IWebBrowser2CComQIPtr m_spWebBrowser2;
STDMETHOD(SetSite)(IUnknown* punkSite) {
m_spWebBrowser2 = punkSite; // 自動 QI
if (m_spWebBrowser2) AdviseEvents(); // 建議事件連接
return S_OK;
}
IConnectionPointContainer + IConnectionPointCComPtr spCP;
CComQIPtr spCPC(m_spWebBrowser2);
spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);
spCP->Advise((IDispatch*)this, &m_dwCookie); // this 實作 IDispatch::Invoke
IDispatch::InvokeSTDMETHOD(Invoke)(DISPID dispid, REFIID, LCID, WORD, DISPPARAMS* p, VARIANT*, EXCEPINFO*, UINT*) {
switch (dispid) {
case DISPID_BEFORENAVIGATE2: // 導航前
case DISPID_NAVIGATECOMPLETE2: // 導航完成
case DISPID_DOCUMENTCOMPLETE: // 文件完成
// p->rgvarg[0] 等包含 URL、Flags 等參數 (VARIANT)
break;
}
return S_OK;
}
關鍵:DISPPARAMS::rgvarg 為 VARIANTARG* 陣列,參數順序依事件定義。
IHTMLDocument2IDispatchPtr spDisp;
m_spWebBrowser2->get_Document(&spDisp);
CComQIPtr spDoc(spDisp);
// 取得 URL
_bstr_t url = spDoc->get_URL();
// 取得所有 Form
MSHTML::IHTMLElementCollectionPtr spForms = spDoc->get_forms();
long len; spForms->get_length(&len);
for (long i = 0; i < len; ++i) {
IDispatchPtr spItem; spForms->item(_variant_t(i), _variant_t(), &spItem);
CComQIPtr spForm(spItem);
// 操作 form 元素...
}
// 元素屬性讀寫
CComQIPtr spElem;
spElem->setAttribute(_bstr_t("value"), _variant_t("自動填入"), 0);
_variant_t val; spElem->getAttribute(_bstr_t("value"), 0, &val);
<form>input、select、textarea 等元素name/id/type 比對本地資料庫setAttribute("value", ...) 填寫IHTMLElementCollection 取得文字節點put_innerText 或 setAttribute 置換BeforeNavigate2、DocumentComplete 事件| 限制 | 說明 | 現代替代 |
|---|---|---|
| 僅限 IE | Edge/Chrome/Firefox 不支援 BHO | WebExtension (Manifest V3)、Chrome DevTools Protocol |
| 安全性限制 | 增強保護模式 (EPM) 隔離 BHO | AppContainer、Medium IL 隔離 |
| 64 位元相容 | 需編譯 64 位元 DLL | 通用二進位或分架構部署 |
| DOM 不完整 | 不支援動態增刪節點 (早期版本) | 現代 IE/Edge 完整支援 W3C DOM Level 2/3 |
IE 自動化技術雖屬經典,但其 COM 架構、事件模型、DOM 操作思想通用於現代瀏覽器擴充開發。理解這些核心機制,有助於跨平台瀏覽器自動化方案的設計。