我正在实施一个应该捕获 DISPID_FILEDOWNLOAD 事件的Internet Explorer浏览器帮助程序对象。
我首先在C#中实现了这个功能,除了我还需要带有URL的cookie所以需要调用InternetGetCookiesEx之外,它工作得很好。由于.NET在它自己的进程中运行,它不会返回会话cookie,所以不好。
然后我用C ++编写了一个快速测试DLL,以便将它加载到与IE相同的过程中,这对于cookie非常有用,但我现在遇到了一个新问题:
我在调用函数中为每个页面加载调用 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事件:
显然我只想在实际的下载活动中使用偶数。
答案 0 :(得分:0)
作为一种可能的解决方案,我注意到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事件,我不这样做..只有新的标签/浏览器实例和一些新连接。
希望其他人能够为此做出贡献并澄清处理此问题的最佳方式,因为它感觉有点像黑客。