2

We are developing an application which needs to interact with the active document in IE.

Context: The app is a C#, .Net 3.5 desktop app. The goal is to highlight specific text elements in the web page on user request. For this we need to retrieve and interpret web page elements (the need for the return value) then act on them through another JS call. The operations that must be made in the web page are not all done at the same time so we must get some kind of "snapshot" of the interesting text elements (we do this on the Mac version of our app by returning a string containing an XML representation of those elements).

In .Net we used IHTMLDocument2's execScript method successfully to run some JavaScript inside the active IE document, but we can't seem to find a way to get a return value from the call. Based on the doc execScript returns an execution success/failure constant which is not what we need.

In essence what we need to do is to load some JavaScript from a text file into a string, then send it to IE for execution. Then we need to get a string back from the called script.

Any hints on what objects to use? How to proceed to get this functionality?

Thanks in advance!

My colleague found the solution, based on what Alun Harford said:

string jsToRun = "function myTest() { return document.title; } myTest();";
mshtml.IHTMLDocument2 myIHTMLDocument2 = GetSelectedIEWindow();
IE ie = IE.AttachToIE(Find.ByUrl(myIHTMLDocument2.url));
string jsReturn = ie.Eval(jsToRun);

jsReturn then contains the string value returned from myTest() in JavaScript. Note that there is no return before the myTest() function call in the script!

6
  • Web Services or Ajax? Are JSON and jQuery allowed? Commented Nov 10, 2009 at 21:35
  • It's actually from a desktop .Net application, not from ASP. Commented Nov 10, 2009 at 21:35
  • It sounds suspiciously virusy. I wouldn't be surprised if it wasn't possible due to security restrictions. Commented Nov 10, 2009 at 21:37
  • Actually it's not for a virus (!) it's for highlighting text in the browser. You are right that could be a security concern, but personally I think calling JS in the active web page (which is very easy to do) is as big a security concern as getting content from the HTML page but it's not prevented at all. I'm sure there must be a way to do this. We do it on the Mac version of our application through AppleScript. Commented Nov 10, 2009 at 21:41
  • it's not a virus, this sort of functionality has legitimate usage particularly in the accessibility arena. Commented Nov 10, 2009 at 22:02

3 Answers 3

2

Have a look at the WatiN codebase. In there, IE.Eval does exactly what you're looking for.

Sign up to request clarification or add additional context in comments.

1 Comment

That did the job! It's very easy to use too. See my original question for the code.
2

If you are providing the html and script yourself you can do the following:

  • execute the javascript function
  • let the js function place the result in an html element
  • wait till the function is done running
  • retrieve the html element using document.getElementById
  • and retrieve the value

I'm not sure if there's a easier way to do this.

4 Comments

Unfortunately the goal of the app is to highlight text in existing web pages on request by the user when they browse the Web. So I need to be able to send my JS code from the .Net desktop app, have IE run it, then get the return the string value from the function that was ran.
You can add a hidden element using document.write or some other function. And then use that element in your javascript code.
I see what you mean but what I need is a method or object in .Net to retrieve the return value (or the hidden element's value) in question.
Use HtmlElement element = m_webBrowser.Document.GetElementById("[ID]") and then element.InnerHtml or element.GetAttribute("[AttributeName]") depends on what you want to use
1

Well it is nasty but it can be done.

Try this:

    [Guid("626FC520-A41E-11CF-A731-00A0C9082637"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
    interface IHTMLDocument
    {
        void Script([Out, MarshalAs(UnmanagedType.Interface)] out object ppScript);
    }

    public object RunScript(InternetExplorer ie, string scriptText)
    {                        
        IHTMLDocument doc = (IHTMLDocument)ie.Document;
        object scriptObj;
        doc.Script(out scriptObj);

        Type t = scriptObj.GetType();
        return t.InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, scriptObj, new object[] { scriptText });            
    }

That will return your value in the object (just cast to what ever type you expected). Of course .NET 4 makes this even easier ;)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.