简体   繁体   中英

How to send JavaScript code to IE using C# (.Net 3.5), run it, then get a string return value from the JS code?

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!

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.

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

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 ;)

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