How to detect Javascript execution in WebBrowser control

11,024

Solution 1

You can use window.external to call a C# method when a global function is fired in JavaScript. See WebBrowser Control Overview for details on window.external.

You'll need to set ObjectForScripting: Webbrowser control's window.external is ALWAYS null. for this to work.

Take @Krishna's answer to add the JavaScript (but drop jQuery because it won't be needed):

private void addScript(HtmlElement head, string scriptSource) 
{ 
HtmlElement lhe_script = head.Document.CreateElement("script"); 
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
script.src = scriptSource;
head.AppendChild(lhe_script);            
} 

addScript(WebBrowser.Head, @"InjectMonitor.js");

The JavaScript below (InjectMonitor.js) will find all global functions and attach your specified handler:

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];
        if (typeof fn === 'function') {
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    fn.apply(this, arguments);

                };
            })(name, fn);
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name, fn);

    // window.external.yourC#method
});

In this example, taken from Adding Console Log to Every Function, it just logs the call to console; but using window.external you could send some message back to your C# application with details of what function was called from the client.

Finally, here's a JS Bin example (run it and don't forget the console): JS Bin Example

Solution 2

On the webbrowser load event,

  1. Inject Jquery
  2. Inject Monitor scripts

,

private void addScript(HtmlElement head, string scriptSource) 
{ 
HtmlElement lhe_script = head.Document.CreateElement("script"); 
IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
script.src = scriptSource;
head.AppendChild(lhe_script);            
} 

addScript(Webbrowser.Head, @"<Change File Path here>jquery.min.js");
addScript(WebBrowser.Head, @"InjectMonitor.js");

your file InjectMonitor.js should be something like this

 $(document).ready(function () { 
        //Add click event for every anchor on the page loaded- note this merely alerts text on click. you can however add your own function
        $("a").click(function (e) { alert($(this).text()); return false;}) 
    }); 

Solution 3

Well what krishna has answered is interms of pure javascript attaching to events, however i see that you might need to attach it to all the tags(a,p,div,input) etc and to all the events attached to each tag.

i believe the another way is to play around with the BHO(browser helper object) available to your in .net, and if not and you are good at VC++ and MFC you can also play around with Windows Hooks.

Share:
11,024
Gabber
Author by

Gabber

C#, Java, web (drupal, js) developer. Degree cum laude in computer science got in Italy, usually also bass player. I am not truly a gabber, my first name sounds like that, therefore my friends call me so... Hey! Stack overflow: 1492 rep. Columbus discovers America!

Updated on June 05, 2022

Comments

  • Gabber
    Gabber almost 2 years

    I have a WebBrowser control in my C# application. The web browser is under the user's control, that is, he can load any web page his computer can access on the web (of course limited by proxy, hosts file and so on).

    I need to know and to be notified when there is a Javascript call inside the page loaded in the web browser component.

    First example: given a link like this

    <a href="javascript:void(0)" onclick="jsFunct();">test</a>
    

    When the user clicks the link I need to know that the function "jsFunct" has been called.

    Second example: given a call like

    <script type="text/javascript">
        window.setTimeout("jsFunct()", 1000);
    </script>
    

    I need to know that, 1 second after the execution of the script, the function jsFunct has been called.

    The best thing would be to have an event fired when the function is called. It would also be great if the event could get the Javascript code executed, or at least the function name in the arguments.

    EDIT:

    Even if the question is related to the webbrowser component, anything that allows the user to detect javascript activation (even via js) would be fine, being able to inject a js that handles the javascript event and passes it to the wb control triggering some event that it can handle.