IConnectionPoint :: Advise方法(COM)正在减慢Excel 2016启动速度

时间:2017-11-13 08:31:11

标签: com dde

在我的应用程序中,我使用IConnectionPoint::Advise方法获取与ADODB::ConnectionEvents实现的连接。

调用Advise时,文件关联启动Excel需要花费大量时间(例如,点击.csv文件)。

Process Monitor内观看启动只显示了5到15秒的时间段,似乎没有任何事情发生。

我在MSVC中做了一个小例子来说明确切的问题:

::CoInitialize(NULL);
IConnectionPointContainer *pCPC = NULL;
IConnectionPoint *pCP = NULL;
ADODB::_ConnectionPtr pConn;
HRESULT hr;
hr = pConn.CreateInstance(__uuidof(ADODB::Connection));

hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer), (void **)&pCPC);
hr = pCPC->FindConnectionPoint(__uuidof(ADODB::ConnectionEvents), &pCP);
pCPC->Release();

DWORD dwConnEvt;
IUnknown *pUnk = NULL;
CConnEvent *pConnEvent= NULL;
pConnEvent = new CConnEvent(hEvent);
hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
hr = pCP->Advise(pUnk, &dwConnEvt);
...

和CConnEvent:

class CConnEvent : public ADODB::ConnectionEventsVt {
private:
   ULONG m_cRef;
   HANDLE _hEvent;

public:
   CConnEvent(HANDLE &hEvent) : _hEvent(hEvent)
   { m_cRef = 0; };
   ~CConnEvent() {};

   STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
   {
      *ppv = NULL;
      if (riid == __uuidof(IUnknown) || riid == __uuidof(ConnectionEventsVt))
         *ppv = this;

      if (*ppv == NULL)
         return ResultFromScode(E_NOINTERFACE);

      AddRef();
      return NOERROR;
   }
   STDMETHODIMP_(ULONG) AddRef()
   {
      return ++m_cRef;
   }
   STDMETHODIMP_(ULONG) Release()
   {
      if (0 != --m_cRef)
         return m_cRef;
      delete this;
      return 0;
   }

   STDMETHODIMP raw_InfoMessage( struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_BeginTransComplete( LONG TransactionLevel,
   struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_CommitTransComplete( struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_RollbackTransComplete( struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_WillExecute( BSTR *Source,
      ADODB::CursorTypeEnum *CursorType,
      ADODB::LockTypeEnum *LockType,
      long *Options,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Command *pCommand,
   struct ADODB::_Recordset *pRecordset,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_ExecuteComplete( LONG RecordsAffected,
   struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Command *pCommand,
   struct ADODB::_Recordset *pRecordset,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      {
         ::SetEvent(_hEvent);
      }
      return S_OK;
   }

   STDMETHODIMP raw_WillConnect( BSTR *ConnectionString,
      BSTR *UserID,
      BSTR *Password,
      long *Options,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_ConnectComplete( struct ADODB::Error *pError,
      ADODB::EventStatusEnum *adStatus,
   struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }

   STDMETHODIMP raw_Disconnect( ADODB::EventStatusEnum *adStatus, struct ADODB::_Connection *pConnection)
   {
      *adStatus = ADODB::adStatusOK;
      return S_OK;
   }
};

任何帮助都将不胜感激。

0 个答案:

没有答案