Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a jQuery function from .NET WebBrowser control using InvokeScript()?

Had a Windows Forms app using a WebBrowser control (.NET 4) to load a web page that communicated with the app. I had a call to InvokeScript() to call a Javascript routine in the web page at one point.

Now things have been "updated", and jQuery is now being used. So instead of having a OnVenueSelected() function to call, it's now some $.city.venue.onVenueSelected: function(param) oddity.

Simply changing my call from InvokeScript("OnVenueSelected", new object[] { params }) to InvokeScript("$.city.venue.onVenueSelected", new object[] { params }) did not work. I don't get any observable errors or exceptions, but the logic in the call is not invoked.

Some digging around had me trying to use eval as the call and passing the function name and parameters as the string to eval. That didn't work either.

Is there a known way to invoke a function that's embedded in a couple of layers of jQuery magic?

Thanks.

like image 705
GuyWithDogs Avatar asked Feb 08 '12 05:02

GuyWithDogs


3 Answers

OK - I get to answer my own question. Thanks in part to the answer by at How to call a jQuery function from .NET WebBrowser control using InvokeScript()?, I was able to change my call to the jQuery function to

string[] codeString = { String.Format(" {0}('{1}') ", @"$.city.venue.onVenueSelected", result.ToString()) };
this.myBrowser.Document.InvokeScript("eval", codeString);

Amazingly enough, this seems to be working.

In my case, the result variable is of type bool (in case that matters to anyone).

like image 94
GuyWithDogs Avatar answered Oct 20 '22 15:10

GuyWithDogs


For those that may not be aware, you can also use .execScript in pre-.NET versions of WB control and current/.NET versions of WB control. You can also choose the language of the script you want to execute, ie: "JScript" or "VBScript". Here is the one liner:

WebBrowser1.Document.parentWindow.execScript "alert('hello world');", "JScript"
like image 37
Erx_VB.NExT.Coder Avatar answered Oct 20 '22 15:10

Erx_VB.NExT.Coder


Yeah, that is probably the quickest way to do that, because the 'invokescript' simply needs to be given a name of a global function. So after pushing the functions down deeper into some structures, and to still be able to call them via InvokeScript in a "more pretty" way, you would have to, for example, write a single GLOBAL wrapper (a 'dispatcher' would be a better name), similar to the:

function callme(what, args) {
   var actualfunction = eval(what);   // or any other way to parse the 'what' and get a function
   return actualfunction(args);
}

and later call it:

  • from JS:

    callme("$.city.venue.onVenueSelected", ..args..)
    

    (but I truly dont know why you could want to call it from JS :))

  • and from CS:

    browser.InvokeScript("callme", new string[]{ "$.city.venue.onVenueSelected", ..args.. })
    

this way, I think you would be able to pass objects as function arguments directly, without stringifying them

..but from my experience, in >80% of the cases, you just need to pass some simple numbers and strings or setup flags, so all that hassle is usually just a code bloat

like image 20
quetzalcoatl Avatar answered Oct 20 '22 15:10

quetzalcoatl