Windows 兩大瀏覽器:檔案總管 (explorer.exe) 與 IE (iexplore.exe)。為新增功能而重寫瀏覽器工程量大、屬重複造輪子。BHO 是實作特定介面的 COM 元件,註冊至特定登錄機碼後,IE 啟動即建立 BHO 實例,接收導航、前進後退、新視窗、退出等事件,實現與瀏覽器深度互動。
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects 下的 CLSID 子機碼IObjectWithSite::SetSite 傳入瀏覽器 IUnknown 指標QueryInterface 取得 IWebBrowser2、DWebBrowserEvents2 等介面,建立事件連接點
| Shell 版本 | 作業系統 | 支援範圍 |
|---|---|---|
| 4.00 | Win95/NT4 (IE4) | 僅 IE4 |
| 4.71 | Win95/NT4 (IE4) | IE + 檔案總管 |
| 4.72 | Win98 | IE + 檔案總管 |
| 5.00 | Win2000 | IE + 檔案總管 |
專案名 BhoPlugin,預設設定。插入 ATL Object,選 Internet Explorer Object,Short Name 輸入 EyeOnIE。產生的 CEyeOnIE 繼承 IObjectWithSiteImpl。
// EyeOnIE.h
CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;
DWORD m_dwCookie;
// EyeOnIE.cpp
STDMETHODIMP CEyeOnIE::SetSite(IUnknown *pUnkSite) {
if (pUnkSite) {
m_spWebBrowser2 = pUnkSite; // 保存瀏覽器指標
// 向瀏覽器註冊事件接收器
return AtlAdvise(m_spWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &m_dwCookie);
}
else {
// 註銷事件接收器
if (m_dwCookie) AtlUnadvise(m_spWebBrowser2, DIID_DWebBrowserEvents2, m_dwCookie);
m_spWebBrowser2.Release();
}
return IObjectWithSiteImpl<CEyeOnIE>::SetSite(pUnkSite);
}
事件 ID 定義於 ExDispID.h。範例攔截 DISPID_BEFORENAVIGATE2 實作網址過濾:
STDMETHODIMP CEyeOnIE::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) {
if (dispIdMember == DISPID_BEFORENAVIGATE2) {
// 參數順序:URL, Flags, TargetFrameName, PostData, Headers, Cancel
VARIANT *pUrl = &pDispParams->rgvarg[5];
VARIANT *pCancel = &pDispParams->rgvarg[0];
if (pUrl->vt == VT_BSTR && wcsstr(pUrl->bstrVal, L"girl.com")) {
MessageBox(NULL, L"偵測到受限網站!", L"警告", MB_OK);
pCancel->boolVal = VARIANT_TRUE; // 取消導航
}
}
else if (dispIdMember == DISPID_QUIT) {
// 瀏覽器退出時註銷事件
if (m_dwCookie) AtlUnadvise(m_spWebBrowser2, DIID_DWebBrowserEvents2, m_dwCookie);
}
return S_OK;
}
// DllMain 中判斷載入者
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) {
if (dwReason == DLL_PROCESS_ATTACH) {
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH);
if (_tcsstr(_tcslwr(szPath), _T("explorer.exe"))) return FALSE; // 拒絕載入
}
return _Module.DllMain(dwReason, lpReserved);
}
HKLM {
SOFTWARE {
Microsoft {
Windows {
CurrentVersion {
Explorer {
'Browser Helper Objects' {
{YOUR_CLSID_HERE} // 替換為專案實際 CLSID
}
}
}
}
}
}
}
停用:regsvr32 /u yourbho.dll 或刪除登錄機碼。BHO 還可實現網頁內容分析、IE 介面客製化、安裝鉤子監控等進階功能。