简体   繁体   中英

IE extension to inject javascript in the webpage

I have implemented an IE extension using C++. Its function is to inject javascript in the webpage's head tag, whenever the extension icon is clicked. I have used execScript method for script injection.
It works fine but when I refresh the webpage, or when I click on any link on the webpage, or when I enter another URL the injected script vanishes away.
I don't want the script to vanish away, I want it to be persistent inside the web browser.
How can I achieve that? I am new to IE extension development, any help would be highly appreciated.
Thanks.

STDMETHODIMP CBlogUrlSnaggerAddIn::Exec(
const GUID *pguidCmdGroup, DWORD nCmdID,
DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut){
    HRESULT hr = S_OK;
    CComPtr<IDispatch> spDispDoc;
    hr = m_spWebBrowser->get_Document(&spDispDoc);
    if (SUCCEEDED(hr)){ 
        CComPtr<IDispatch> spDispDoc;
        hr = m_spWebBrowser->get_Document(&spDispDoc);
           if (SUCCEEDED(hr) && spDispDoc){
              CComPtr<IHTMLDocument2> spHTMLDoc;
              hr = spDispDoc.QueryInterface<IHTMLDocument2>( &spHTMLDoc );
                  if (SUCCEEDED(hr) && spHTMLDoc){
                       VARIANT vrt = {0};
                       CComQIPtr<IHTMLWindow2> win;
                       hr = spHTMLDoc->get_parentWindow(&win);
                       CComBSTR bstrScript = L"function fn() {alert('helloooo');}var  head = document.getElementsByTagName('head')[0],script = document.createElement('script');script[script.innerText ? 'innerText' : 'textContent'] = '(' + fn + ')()';head.appendChild(script);head.parentNode.replaceChild(script,'script');";
                       CComBSTR bstrLanguage = L"javascript";
                       HRESULT hrexec = win->execScript(bstrScript,bstrLanguage, &vrt);
    }
}}

Instead of writing the execScript code in the Exec event, try adding the piece of code under OnDocumentComplete method. Use the Sink map which is used to set up event handling. A sample is provided below.

BEGIN_SINK_MAP(CMyClass)
    SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2,DISPID_DOCUMENTCOMPLETE , OnDocumentComplete)

END_SINK_MAP()

Implement the DocumentComplete in your class file.

void STDMETHODCALLTYPE CMyClass::OnDocumentComplete(IDispatch *pDisp,VARIANT *pvarURL)
{
   //Inject the scripts here
}

Updated :

I haven't tried this, but I guess DownloadBegin event would serve your purpose. It is similar to the the Document complete event mapped, only thing which would differ would be the DISPID_DOWNLOADBEGIN. Map a corresponding handler method to the DISPID and give it a try.

BEGIN_SINK_MAP(CMyClass)
    SINK_ENTRY_EX(1,DIID_DWebBrowserEvents2,DISPID_DOWNLOADBEGIN, OnDocumentLoad)
END_SINK_MAP()

Similar to DocumentComplete Handler method

void STDMETHODCALLTYPE CMyClass::OnDocumentLoad(IDispatch *pDisp,VARIANT *pvarURL)
{
   //Inject scripts here
}

http://msdn.microsoft.com/en-us/library/cc136547(v=vs.85).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM