IE BHO - DISPID_FILEDOWNLOAD被调用页面加载?

时间:2014-08-17 11:08:13

标签: c++ windows internet-explorer bho wininet

我正在实施一个应该捕获 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事件:

  1. 新窗口/标签页已打开
  2. 新域连接到(可能是一个新的保持连接?)
  3. 实际下载
  4. 显然我只想在实际的下载活动中使用偶数。

1 个答案:

答案 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事件,我不这样做..只有新的标签/浏览器实例和一些新连接。

希望其他人能够为此做出贡献并澄清处理此问题的最佳方式,因为它感觉有点像黑客。