IWebBrowser2 Crashes When Navigating to Amazon Japan

4

I've been trying to fix a problem involving the IWebBrowser2 and the Amazon Japan website (http://www.amazon.co.jp). Every time I visit this site, my application hosting the web browser crashes.

This hasn't happened before with this particular site. In fact, it was working for several months until last week when it just keep crashing. I could load other websites perfectly except Amazon Japan.

I noticed in the debugging window that I got several first-chance exceptions before the app froze.

Debugging Output 1 (Amazon Japan)

First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x002fd2ac..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x002fd30c..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x002fc844..

But I don't think this is the cause of the problem as I'm also getting these exceptions when loading Amazon US (www.amazon.com). In fact, it has even more, but my hosting app doesn't crash.

Debugging Output 2 (Amazon US)

First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6cfec..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6d04c..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6c584..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6dd8c..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6db9c..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6e3cc..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: Microsoft C++ exception: Js::JavascriptExceptionObject at memory location 0x00f6db9c..
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: 0x80040155: Interface not registered.
First-chance exception at 0x763c4b32 in IWebBrowser2.exe: 0x80040155: Interface not registered.

Yahoo.com and some other sites I used for testing also loaded fine despite having these exceptions. Also note that the second debugging output above shows two first-chance exceptions with "Interface not registered." I didn't get this for yahoo.com and those other sites.

My Attempts to Fix the Problem

When I first encountered this, I thought it was just a scripting error on the site. However, I didn't see any Javascript error boxes from IWebBrowser2, but just to be sure, I called the put_silent(...) method of the IWebBrowser2 object.

m_pWebBrowser->put_silent(VARIANT_TRUE);

It still crashed. I also unchecked the "Disable script debugging (Internet Explorer)" and or the "Disable script debugging (Other)" in the Advanced options of Internet Explorer. That also didn't work.

Then I thought perhaps IWebBrowser2 needed to emulate IE8 or some newer version of IE to handle Amazon Japan. So, I added every browser emulation described in this MSDN link into the registry for my app. And that didn't fly either.

I also added an exception breakpoint for "Js::JavascriptExceptionObject" so that Visual Studio will stop at the location of the first Js::JavascriptExceptionObject exception. The exception occurred within my GetMessage(...) while-loop.

MSG msg = { 0 };
while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg); // <--- Js::JavascriptExceptionObject exception was caught here.
}

That didn't help me at all. Next, I searched on Stackoverflow for the same or similar problem and I found a couple of entries posted months ago.

Plenty exceptions when using webbrowser control c#

Debugging javaScript in Visual studio. First chance exceptions

Both mentioned the same "first-chance" exception that I have. The poster of the first link did say that his program crashed after five minutes of continuous running. Mine crashes right away after a few exceptions. The second didn't mention of any crashes. Both questions have no accepted solutions. Also, the posters didn't provide codes that might help troubleshoot the issue. So, I'm going to do that.

Without further ado, here are my codes.

MAIN.H

#include <string>
#include <windows.h>
#include "WebBrowser.h"

int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);

MAIN.CPP

#include "Main.H"

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR pszCmdLine, int nCmdShow)
{
    OleInitialize(NULL);

    std::wstring classname = L"IWebBrowser2 Crash";

    WNDCLASS wc      = { 0 };
    wc.hInstance     = hInstance;
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WindowProc;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpszClassName = classname.c_str();
    if(!RegisterClass(&wc))
        return 0;

    SIZE size = { 800, 600 };

    HWND hWindow = ::CreateWindow(classname.c_str(), classname.c_str(), WS_OVERLAPPEDWINDOW, 0,     
                                    0, size.cx, size.cy, NULL, NULL, hInstance, 0);
    if(!hWindow)
        return 0;

    ShowWindow(hWindow, SW_SHOW);
    UpdateWindow(hWindow);

    MSG msg = { 0 };
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static WebBrowser web;

    switch(uMsg)
    {
    case WM_CREATE:
        {
            RECT r = { 0 };
            ::GetClientRect(hWnd, &r);
            if(web.Create(hWnd, r.right, r.bottom, (HINSTANCE)GetModuleHandle(NULL)))
            {
                web.Show();
                // web.Navigate(L"www.yahoo.com");
                web.Navigate(L"www.amazon.co.jp");
            }
        }
        return 0;    

    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

WEBBROWSER.H

#include <exdisp.h>
#include <MSHTML.H>
#include <initguid.h>

#include <oleidl.h>
#include <ole2.h>
#pragma comment(lib, "ole32.lib")

//
#include <comip.h>
#include <comdef.h>
#include <comutil.h>
#ifdef _DEBUG
    #pragma comment(lib, "comsuppwd.lib")
#else
    #pragma comment(lib, "comsuppw.lib")
#endif

class WebBrowser: public IOleClientSite, public IOleInPlaceSite, public IOleInPlaceFrame, 
                  public IStorage
{
    HWND            m_hWindow;
    IOleObject *    m_ptrOleObj;
    ULONG           m_refcount;
    IWebBrowser2 *  m_pWebBrowser;

    //
    // IUnknown
    //

    STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObject)
    {   
        if(riid == IID_IUnknown)
            *ppvObject = (LPUNKNOWN)(LPVOID)this;
        else if(riid == IID_IOleClientSite)
            *ppvObject = (LPOLECLIENTSITE)this;
        else if(riid == IID_IOleInPlaceSite)
            *ppvObject = (LPOLEINPLACESITE)this;
        else if(riid == IID_IOleInPlaceFrame)
            *ppvObject = (LPOLEINPLACEFRAME)this;
        else if(riid == IID_IStorage)
            *ppvObject = (LPSTORAGE)this;
        else 
        {   
            *ppvObject = NULL;
            return E_NOINTERFACE;
        }   

        // 
        ((LPUNKNOWN)*ppvObject)->AddRef();
        return S_OK;
    }

    STDMETHODIMP_(ULONG) AddRef(void)
    {   
        return ++m_refcount;
    }

    STDMETHODIMP_(ULONG) STDMETHODCALLTYPE Release(void)
    {   
        if(--m_refcount <= 0)
            m_refcount = 0;    

        return m_refcount;
    }    

    //
    // IOleWindow 
    //    

    STDMETHODIMP GetWindow(HWND * phWindow)
    {   
        *phWindow = m_hWindow;
        return S_OK;
    }

    STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode)
    {   
        return E_NOTIMPL;
    }    

    //
    // IOleInPlaceUIWindow
    //        

    STDMETHODIMP GetBorder(LPRECT lpRectBorder)
    {   return E_NOTIMPL;
    }
    STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
    {   return E_NOTIMPL;
    }
    STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject *pActiveObject,  LPCOLESTR pszObjName)
    {   return E_NOTIMPL;
    }
    STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
    {   return E_NOTIMPL;
    }    

    //
    // IOleInPlaceFrame
    //

    STDMETHODIMP EnableModeless(BOOL fEnable)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP RemoveMenus(HMENU hmenuShared)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP SetStatusText(LPCOLESTR pszStatusText)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP TranslateAccelerator(LPMSG lpmsg,  WORD wID)
    {   return E_NOTIMPL;
    }    

    // 
    // IOleClientSite
    //     

    STDMETHODIMP SaveObject()
    {   return E_NOTIMPL;
    }

    STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP GetContainer(LPOLECONTAINER FAR* ppContainer)  
    {   
        * ppContainer = NULL;
        return E_NOINTERFACE;
    }

    STDMETHODIMP ShowObject()
    {   return S_OK;
    }

    STDMETHODIMP OnShowWindow(BOOL fShow)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP RequestNewObjectLayout()
    {   return E_NOTIMPL;
    }       

    //
    // IOleInPlaceSite
    //    

    STDMETHODIMP CanInPlaceActivate()
    {   return S_OK;
    }

    STDMETHODIMP DeactivateAndUndo()
    {   return E_NOTIMPL;   
    }

    STDMETHODIMP DiscardUndoState()
    {   return E_NOTIMPL;   
    }

    STDMETHODIMP GetWindowContext(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, 
                  LPRECT  prcPosRect, LPRECT prcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
    {
        if(m_hWindow)
        {
            RECT rSize = { 0 };
            GetClientRect(m_hWindow, &rSize);        

            //
            *ppFrame                    = (LPOLEINPLACEFRAME)this;
            *ppDoc                      = NULL;
            *prcPosRect                 = rSize;
            *prcClipRect                = rSize;
            lpFrameInfo->fMDIApp        = FALSE;
            lpFrameInfo->hwndFrame      = m_hWindow;
            lpFrameInfo->haccel         = NULL;
            lpFrameInfo->cAccelEntries  = 0;
        }

        return S_OK;
    }

    STDMETHODIMP OnInPlaceActivate()
    {   return S_OK;    
    }

    STDMETHODIMP OnInPlaceDeactivate()
    {   return S_OK;
    }

    STDMETHODIMP OnPosRectChange(LPCRECT prcPosRect)
    {   
        return S_OK;
    }

    STDMETHODIMP OnUIActivate()
    {   return S_OK;
    }

    STDMETHODIMP OnUIDeactivate(BOOL fUndoable)
    {   return S_OK;
    }

    STDMETHODIMP Scroll(SIZE scrollExtent)
    {   return E_NOTIMPL;
    }

    //
    // IStorage
    //    

    STDMETHODIMP CreateStream(const WCHAR * pwcsName, DWORD dwMode, DWORD dwReserved1, 
                              DWORD dwReserved2, LPSTREAM * ppstm)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP OpenStream(const WCHAR * pwcsName, void * pvReserved1, DWORD dwMode, 
                            DWORD dwReserved2, LPSTREAM * ppstm)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP CreateStorage(const WCHAR * pwcsName, DWORD dwMode, DWORD dwReserved1, 
                               DWORD dwReserved2, LPSTORAGE * ppstg)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP OpenStorage(const WCHAR * pwcsName, LPSTORAGE pstgPriority, DWORD dwMode, 
                             SNB snbExclude, DWORD dwReserved, LPSTORAGE * ppstg)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP CopyTo(DWORD ciidExclude, IID const * rgiidExclude, SNB snbExclude, 
                        LPSTORAGE pstgDest)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP MoveElementTo(const WCHAR * pwcsName, LPSTORAGE pstgDest, LPCWSTR pwcsNewName, 
                               DWORD dwFlags)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP Commit(DWORD dwCommitFlags)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP Revert()
    {   return E_NOTIMPL;
    }

    STDMETHODIMP EnumElements(DWORD dwReserved1, VOID * pvReserved2, DWORD dwReserved3,
                              IEnumSTATSTG ** ppenum)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP DestroyElement(const WCHAR * pwcsName)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP RenameElement(const WCHAR * pwcsOldName, const WCHAR * pwcsNewName)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP SetElementTimes(const WCHAR * pwcsName, FILETIME const * pctime, 
                             FILETIME const * patime, FILETIME const * pmtime)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP SetStateBits(DWORD dwStateBits, DWORD dwMask)
    {   return E_NOTIMPL;
    }

    STDMETHODIMP Stat(STATSTG * pstatstg, DWORD dwStatFlag)
    {   return E_NOTIMPL;
    }   

    STDMETHODIMP SetClass(REFCLSID clsid)
    {   return S_OK;
    }

public:

    WebBrowser() : m_hWindow(NULL), m_refcount(0), m_ptrOleObj(NULL), m_pWebBrowser(NULL) {}

    static LRESULT CALLBACK EventHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    bool Create(HWND hParent, int width, int height, HINSTANCE hInstance)
    {
        WNDCLASS wc = { 0 };
        wc.hInstance = hInstance;
        wc.style = CS_VREDRAW | CS_HREDRAW;
        wc.lpszClassName = L"WebBrowser";
        wc.lpfnWndProc = EventHandler;
        wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
        if(!::RegisterClass(&wc))
            return false;

        m_hWindow = CreateWindow(L"WebBrowser", NULL, WS_BORDER | WS_CHILD, 0, 0, width, height,
                                 hParent, NULL, hInstance, 0);
        if(!m_hWindow)
            return false;

        RECT rSize = { 0, 0, width, height };

        // Create the ActiveX WebBrowser control. 
        HRESULT hres = OleCreate(CLSID_WebBrowser, IID_IOleObject, OLERENDER_DRAW, NULL, this,
                                 (LPSTORAGE)this, (LPVOID*)&m_ptrOleObj);
        if(FAILED(hres))
            return false;

        // Inform the object that it is being embedded in an OLE container. 
        if(FAILED(OleSetContainedObject(m_ptrOleObj, TRUE)))
            return false;

        // Show our web browser control. 
        if(FAILED(m_ptrOleObj->DoVerb(OLEIVERB_SHOW, NULL, this, -1, m_hWindow, &rSize)))
            return false;

        // Obtain a pointer to an IWebBrowser interface so we can control the browser. 
        if(FAILED(m_ptrOleObj->QueryInterface(IID_IWebBrowser2, (LPVOID*)&m_pWebBrowser)))
            return false;

        // Suppress scripting error box
        m_pWebBrowser->put_Silent(VARIANT_TRUE);

        return true;
    }

    void Navigate(LPCWSTR pszURL)
    {
        _ASSERTE(m_pWebBrowser != NULL);

        _bstr_t url = pszURL;
        variant_t empty;

        m_pWebBrowser->Navigate(url, &empty.GetVARIANT(), &empty.GetVARIANT(), 
                                &empty.GetVARIANT(), &empty.GetVARIANT());
    }

    void Show()
    {
        ShowWindow(m_hWindow, SW_SHOW);
    }
};


UPDATE: October 29, 2014. A Workaround.

Okay, I came up with a workaround to this problem -- not a solution, but a workaround. And this might do for some people as it does to my case.

What I did was, instead of hosting an IWebBrowser2 control in my application, I used OLE Automation to run an instance of Internet Explorer, obtained its window handle and set my application as its parent.

As a result, it will appear that the web browser is being hosted in my app. There's one caveat, however. This trick doesn't work in Vista, only in Windows 7 and 8. On Windows Vista, Internet Explorer will always open separately using this method regardless if you've obtained its window handle, add WS_CHILD to its style and set your window as your parent. Calling IWebBrowser2::put_Visible(VARIANT_FALSE) to hide the web browser's frame window doesn't work either on Vista as IE opens immediately whether you invoke this method before or after a successful call to CoCreateInstance. This is contrary to what the MSDN manual says about IWebBrowser2.

"When the InternetExplorer object is first created, the application window is hidden. You must set IWebBrowser2::Visible to VARIANT_TRUE to display the application."

It's probably possible to make this trick work in Vista, but it requires more examination and I'm in a hurry. As I've said, it will do for my case since this is just an in-house program and our primary boxes are running Windows 7 and 8.

Again, this is a workaround. Not a solution. So, I'm still hoping someone out there can help figure out the cause of the crash and how to prevent it.

WEBBROWSER.H

#include <shlguid.h>

//
#include <comutil.h>
#ifdef _DEBUG
    #pragma comment(lib, "comsuppwd.lib")
#else
    #pragma comment(lib, "comsuppw.lib")
#endif

class WebBrowser
{
    HWND            m_hBrowser;
    IWebBrowser2 *  m_pWebBrowser;

public:

    WebBrowser() : m_pWebBrowser(NULL) {}

    bool Create(HWND hParent, int width, int height, HINSTANCE hInstance)
    {
        // Use OLE Automation to control Internet Explorer.
        if(FAILED(CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_SERVER, IID_IWebBrowser2,     
                    (LPVOID*)&m_pWebBrowser)))
            return false;

        IServiceProvider* pServiceProvider = NULL;
        if (SUCCEEDED(m_pWebBrowser->QueryInterface(IID_IServiceProvider, 
            (void**)&pServiceProvider)))
        {
            IOleWindow* pWindow = NULL;
            if (SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_IOleWindow,
                (void**)&pWindow)))
            {
                if (SUCCEEDED(pWindow->GetWindow(&m_hBrowser)))
                {
                    SetWindowLong(m_hBrowser, GWL_STYLE, WS_CHILD);
                    SetWindowLong(m_hBrowser, GWL_HWNDPARENT, (LONG)hParent);
                }
                else
                {
                    MessageBox(NULL, L"Unable to obtain window handle of the web browser.",     
                                L"IWebBrowser2", MB_OK);
                }

                pWindow->Release();
            }

            pServiceProvider->Release();
        } 

        return true;
    }

    void Navigate(LPCWSTR pszURL)
    {
        _bstr_t url = pszURL;
        variant_t empty;
        empty.scode = DISP_E_PARAMNOTFOUND;
        empty.vt = VT_ERROR;

        m_pWebBrowser->Navigate(url, &empty.GetVARIANT(), &empty.GetVARIANT(), 
                                &empty.GetVARIANT(), &empty.GetVARIANT());
    }

    void Show()
    {
        ShowWindow(m_hBrowser, SW_SHOW);
    }

    void SetSize(long width, long height)
    {
        SetWindowPos(m_hBrowser, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW);
        SetWindowPos(m_hBrowser, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE | 
                     SWP_NOREDRAW);
    }
};
c++
exception
amazon
iwebbrowser2
asked on Stack Overflow Oct 25, 2014 by Adam Kris • edited May 23, 2017 by Community

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0