Race Condition embedding a BHO object callback ?

Add-in Express™ Support Service
That's what is more important than anything else

Race Condition embedding a BHO object callback ?
I believe I am seeing a race condition when I inject a script to assign my BHO object to 
George Kierstein




Posts: 47
Joined: 2013-05-04
Hi,

I am following one of the several differing examples on how to create an object for my javascript function to use. When I step through it in the debugger it works fine but when I run it generally I am getting the following exception:

System.NullReferenceException: Object reference not set to an instance of an object.

The javascript I inject code:


                    mshtml.IHTMLScriptElement bhoScriptObject =
                    (mshtml.IHTMLScriptElement)HTMLDocument.createElement("script");

                    bhoScriptObject.type = @"text/javascript";
                    bhoScriptObject.text = "window.bhoCallback = null;";
                    ((mshtml.HTMLBody)HTMLDocument.body).appendChild((mshtml.IHTMLDOMNode)bhoScriptObject);



I immediately after attempt to assign a new instance of the bho:


               object scriptEngine = HTMLDocument.Script;
                if (scriptEngine != null)
                {
                    scriptEngine.GetType().InvokeMember(gBhoCallbackName, BindingFlags.SetProperty, null, scriptEngine, new object[] { this });
                }


Is this due to a race condition ?

Is there a way to definitively know when a script has been completely injected and is ready for use ?

Ideas ?

Thanks
G
Posted 09 Jul, 2013 20:42:26 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi George,

Please the code below. Also you need to define 'bhoCallback' as a global variable, e.g. var bhoCallback = null;


        private bool IsTargetDomain(string url)
        {
            try
            {
                if ((!String.IsNullOrEmpty(url)) && (url != "about:blank"))
                {
                    Uri uri = new Uri(url);
                    return uri.Host.StartsWith("www.google.");
                }
            }
            catch
            {
            }

            return false;
        }

        private string ScriptText = "var MyScriptFlag = true;
function done() { alert('hello'); }";

        private bool IsMyScriptInjected()
        {
            try
            {
                if (HTMLDocument != null)
                {
                    object scriptEngine = HTMLDocument.Script;
                    if (scriptEngine != null)
                    {
                        return Convert.ToBoolean(scriptEngine.GetType().InvokeMember(
                            "MyScriptFlag", System.Reflection.BindingFlags.GetProperty, null, scriptEngine, null));
                    }
                }
            }
            catch (Exception)
            {
            }

            return false;
        }

        private void IEModule_DocumentComplete2(object pDisp, string url, bool rootDocLoaded)
        {
            if (rootDocLoaded && (HTMLDocument != null))
            {
                if (IsTargetDomain(url) && (!IsMyScriptInjected()))
                {
                    mshtml.IHTMLScriptElement scriptObject =
                        (mshtml.IHTMLScriptElement)HTMLDocument.createElement("script");
                    scriptObject.type = @"text/javascript";
                    scriptObject.text = "
" + ScriptText + "
";
                    ((mshtml.HTMLBody)HTMLDocument.body).appendChild((mshtml.IHTMLDOMNode)scriptObject);
                }
            }
        }

        private void adxieContextMenuCommandItem1_OnClick(object sender, object htmlElement)
        {
            HTMLDocument.parentWindow.execScript("done();", "JScript");
        }
Posted 10 Jul, 2013 08:19:40 Top
George Kierstein




Posts: 47
Joined: 2013-05-04
Great - Thanks!
Posted 10 Jul, 2013 13:53:40 Top