Connecting to a running instance of Internet Explorer
There are some methods to connect to a running instance of IE. This one is how to connect through the ROT (Running Object Table).
Usually, an application connects to a running instance of another application using the Running Object table. However the Internet Explorer 4.0 doesn't not register itself in ROT. The solution is to write so-called "Browser Helper Object" – a tiny COM object that exposes IObjectWithSite interface and register itself in the ROT. Also it's necessary to register this object in the Registry under the following key:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\The Internet Explorer will create new instance of each Browser Helper Object listed in registry every time new instance of Internet Expoler is started.
HKLM\SOFTWARE\Microsoft\Windows \CurrentVersion\Explorer\Browser Helper Objects\{CE7C3CF0-4B15- 11D1-ABED-709549C10000}
The following code demonstrates how to allow multiple instances of the Internet Explorer to be registered in the ROT using item moniker.
///////////////////////////////////////////////////////////////////////////// IEHELPER.H #ifndef __IEHELPER_H_ #define __IEHELPER_H_ #include "resource.h" // main symbols ///////////////////////////////////////////////////////////////////////////// // CIEHelper class CIEHelper : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CIEHelper, &CLSID_IEHelper>, public IObjectWithSiteImpl<CIEHelper>, public IIEHelper { public: CIEHelper() { m_dwROTID = 0; } ~CIEHelper() { } // IObjectWithSite interface STDMETHOD(SetSite)(IUnknown* pUnkSite); DECLARE_REGISTRY_RESOURCEID(IDR_IEHELPER) BEGIN_COM_MAP(CIEHelper) COM_INTERFACE_ENTRY(IIEHelper) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() // IIEHelper public: void SetROTID(DWORD dwValue) { m_dwROTID = dwValue; } private: DWORD m_dwROTID; void ROT_UnRegister(); void ROT_Register(); }; #endif //__IEHELPER_H_ /////////////////////////////////////////////////////////////////// IEHELPER.CPP // IEHelper.cpp : Implementation of CIEHelper #include "stdafx.h" #include "IE.h" #include "IEHelper.h" #include <initguid.h> #include <exdisp.h> // the IID_IWebBrowser is located over there #include <stdio.h> ///////////////////////////////////////////////////////////////////////////// // CIEHelper // // CObjectWithSite Methods // STDMETHODIMP CIEHelper::SetSite(IUnknown* pUnkSite) { USES_CONVERSION; // remove previously registered object from the table ROT_UnRegister(); // neccessary initialization HRESULT hResult = IObjectWithSiteImpl<CIEHelper>::SetSite(pUnkSite); // register helper object in the running object table ROT_Register(); return hResult; } /////////////////////////////////////////////////////////////////////////// // // // Private Section // const static TCHAR* szMonikerTemplateName = _T("Browser Helper Object"); // // register the object in the running object table // void CIEHelper::ROT_Register() { CComPtr<IRunningObjectTable> pTable; if(GetRunningObjectTable(0, &pTable) == S_OK) { CComBSTR bstrItemName; CComPtr<IMoniker> pMoniker; TCHAR szBuffer[1024]; sprintf(szBuffer, "%s | %d", szMonikerTemplateName, m_spUnkSite); bstrItemName = szBuffer; if(CreateItemMoniker(NULL, bstrItemName, &pMoniker) == S_OK) { DWORD dwRegister; if(pTable->Register(1, (IUnknown*)this, pMoniker, &dwRegister) == S_OK) { SetROTID(dwRegister); ATLTRACE("IIEHelper: the moniker %s has been registered successfully\n", szBuffer); } else { ATLTRACE("IIEHelper: failed to register moniker % s in the ROT\n", szBuffer); } } else { ATLTRACE("IIEHelper: failed to create moniker %s\n", szBuffer); } } else { ATLTRACE("IIEHelper: Could not retrieve the ROT pointer\n"); } } void CIEHelper::ROT_UnRegister() { CComPtr<IRunningObjectTable> pTable; if(GetRunningObjectTable(0, &pTable) == S_OK) { HRESULT hRes = pTable->Revoke(m_dwROTID); ATLTRACE("IIEHelper: ID = %d, result code %x\n", m_dwROTID, hRes); } SetROTID(0); } ////////////////////////////////////////////////////////////////////// IEHELPER.RGS // The following lines should be included into the self-registration portion of // COM application. ... HKLM { SOFTWARE { Microsoft { Windows { CurrentVersion { Explorer { 'Browser Helper Objects' { <CLSID> } } } } } } }
Having implemented and registered the Browser Helper, an application can now obtain the pointer to a running instance of IE by traversing the ROT.
The following example shows the rough method I used to list the instances of IE:
IRunningObjectTable* pTable; if(!FAILED(GetRunningObjectTable(0, &pTable))) { IEnumMoniker* pEnum; if(!FAILED(pTable->EnumRunning(&pEnum))) { IUnknown* pUnknown; IMoniker* pCurMoniker = NULL; LPMALLOC pMalloc; while (pEnum->Next(1, &pCurMoniker, NULL) == S_OK) { if(!FAILED(pTable->GetObject(pCurMoniker, &pUnknown))) { IObjectWithSite* pSite; if(!FAILED(pUnknown->QueryInterface(IID_IObjectWithSite, (void**)&pSite))) { IDispatch* pDispatch; if(pSite->GetSite(IID_IDispatch, (void**)&pDispatch) == S_OK) { CWebBrowserApp browser; browser.AttachDispatch(pDispatch); TRACE("LocationURL: %s\n", browser.GetLocationURL()); TRACE("LocationName: %s\n", browser.GetLocationName()); browser.DetachDispatch(); pDispatch->Release(); } pSite->Release(); } pUnknown->Release(); } pCurMoniker->Release(); } pEnum->Release(); } pTable->Release(); }
MORE INFORMATION
The following file is available for download from the Microsoft Software Library:
~ IEHelper.exe (size: 39958 bytes)