Search code examples
c#javascriptinternet-explorerbhomshtml

C# BHO return value from Javascript


I have a C# BHO which calls some JS functions in a document. Normally I did it like this (and everything worked fine):

IHTMLWindow2 wnd;
//...
wnd.execScript("testMethod(\"testData\");");

But now I need to return value from JS method to my BHO. I implemented test JS method which returns a string but when I use execScript nothing is returned. I started to read documentation about execScript method and found that now they recommend to use eval instead.

But I can't find any information on how to call this from my C# BHO. I have found this question and there is even c# example but it assumes that I host WebBrowser control and suggests to use Document.InvokeScript. And in MSHTML none of IHTMLDocument* interfaces have InvokeScript method. Am I missing something?

EDIT 1: Here is a question which kind of answers how to get return value from execScript. But its probably not smart to use execScript if MSDN says it is no longer supported.

EDIT 2: More code for this issue. First of all I have a JS function like this (in a file called func.js):

getElemHtml = function () {
    var myElem = document.getElementsByClassName("lineDiv")[0];
    // A lot more code goes here...
    alert(myElem.innerHTML);
    return myElem.innerHTML;
}

Then in my BHO I inject this script into the page like this:

StreamReader reader = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("func.js"));
string scriptContent = reader.ReadToEnd();
IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)ihtmlDoc2.all.tags("head")).item(null, 0);
IHTMLScriptElement scriptObject = (IHTMLScriptElement)htmlDoc2.createElement("script");
scriptObject.type = @"text/javascript";
scriptObject.text = scriptContent;
((HTMLHeadElement)head).appendChild((IHTMLDOMNode)scriptObject);

Then in another part of BHO I want to get return value from getElemHtml():

var retVal = ihtmlWindow2.execScript("getElemHtml();");

but retVal is null. I see that script is executed and I see that return value is not null because I see alert window with return value. What I want is a return value from this JS function in my C# BHO code. It looks like this can be done using this answer but as I have said MSDN says I should use eval instead of execScript. The question is how to call eval and get a return value from my JS function.


Solution

  • I have found some links which allow to get return value from JS in C++ BHOs but I haven't managed to convert them in C# so here is a workaround way which worked for me:

    // Execute method and save return value to a new document property.
    ieHtmlWindow2.execScript("document.NewPropForResponse = getElemHtml();");
    
    // Read document property.
    var property = ((IExpando)ieHtmlDocument2).GetProperty("NewPropForResponse", BindingFlags.Default);
    if (property != null)
        return property.GetValue(ieHtmlDocument2, null);  // returns return value from getElemHtml.