IE BHO - 为页面加载调用 DISPID_FILEDOWNLOAD?
Posted
技术标签:
【中文标题】IE BHO - 为页面加载调用 DISPID_FILEDOWNLOAD?【英文标题】:IE BHO - DISPID_FILEDOWNLOAD being called for page loads? 【发布时间】:2014-08-17 11:08:12 【问题描述】:我正在实现一个 Internet Explorer 浏览器帮助对象,该对象应该捕获 DISPID_FILEDOWNLOAD 事件。
我首先在 C# 中实现了这个,效果很好,只是我还需要与 URL 一起使用的 cookie,因此需要调用 InternetGetCookiesEx。由于 .NET 在它自己的进程中运行,它不会向我返回会话 cookie,所以不好。
然后我用 C++ 编写了一个快速测试 DLL,以便将其加载到与 IE 相同的进程中,这对 cookie 非常有用,但我现在遇到了一个新问题:
当我只希望它们用于实际下载时,我在我的 Invoke 函数中为每个页面加载调用 DISPID_FILEDOWNLOAD。
在 C# 版本中,我只接到了对 WebBrowser.FileDownload 的调用以进行实际下载,但似乎 C++ 版本甚至在每次页面加载时都会发送 DISPID_FILEDOWNLOAD。
STDMETHODIMP CIEHlprObj::Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult,
EXCEPINFO* pExcepInfo,
UINT* puArgErr
)
USES_CONVERSION;
if (!pDispParams)
return E_INVALIDARG;
LPOLESTR lpURL = NULL;
m_spWebBrowser2->get_LocationURL(&lpURL);
int i = 0;
switch (dispidMember)
case DISPID_BEFORENAVIGATE2:
case DISPID_BEFORENAVIGATE:
sCurrentFile=NULL;
if (pDispParams->cArgs >= 5 && pDispParams->rgvarg[5].vt == (VT_BYREF | VT_VARIANT))
CComVariant varURL(*pDispParams->rgvarg[5].pvarVal);
varURL.ChangeType(VT_BSTR);
char* myStr = OLE2T(varURL.bstrVal);
if (myStr)
sCurrentFile = AllocateString(myStr);
sCurrentFileW = varURL.bstrVal;
break;
case DISPID_FILEDOWNLOAD:
// CALLED FOR EACH PAGE LOAD!
if(sCurrentFile)
TCHAR cookies[8192];
DWORD size = 8192;
BOOL ret = InternetGetCookieEx(sCurrentFile,
0,
cookies,
&size,
INTERNET_COOKIE_HTTPONLY,
0);
::MessageBox(0, sCurrentFile, "Downloading called multiple times!!", MB_OK);
break;
default:
break;
return S_OK;
是否有一些过滤器需要在某处检查以了解 DISPID_FILEDOWNLOAD 事件是否与文件加载或实际文件下载相关?
非常感谢
更新:
仔细观察,似乎 C# 托管代码版本实际上也在做同样的事情,只是我第一次没有注意到它。
似乎在以下情况下调用了 FileDownload 事件:
-
新窗口/标签打开
新域已连接(可能是新的保持连接?)
实际下载
显然我只想要实际下载事件的偶数。
【问题讨论】:
【参考方案1】:作为一个可能的解决方案,我注意到 MS 提供了一个 ActiveDocument (BOOL) 参数以及事件。根据 Microsoft 文档,ActiveDocument 参数的含义是:
一个布尔值,指定文件是否为活动文档
http://msdn.microsoft.com/en-us/library/bb268220(v=vs.85).aspx
不是很有帮助,但如果我将 DISPID_FILEDOWNLOAD 事件记录到文本文件并稍后查看它们,似乎我应该忽略 ActiveDocument = true 的所有事件
获取参数非常简单:
BOOL cancel = *pDispParams->rgvarg[0].pboolVal;
BOOL active = pDispParams->rgvarg[1].boolVal;
所以代码只需要更新为:
if (active)
return S_OK;
我只能假设这是 IE 发送的某个事件,告诉 BHO 一个页面正在下载.. 不是一个文件,尽管这应该意味着我在每个页面加载时都会收到一个 DISPID_FILEDOWNLOAD 事件,但我没有.. 只有新的标签/浏览器实例和一些新的连接。
希望其他人能够为此做出贡献并阐明处理此问题的最佳方法是什么,因为这感觉有点像 hack。
【讨论】:
以上是关于IE BHO - 为页面加载调用 DISPID_FILEDOWNLOAD?的主要内容,如果未能解决你的问题,请参考以下文章
在IE的管理加载项里有个这个BHO.BrowserMonitor,请问是啥东西?
ActiveX 或 BHO(Internet Explorer)