Calling a JavaScript Function in The C# Webbrowser Control

Calling a Javascript function in the C# webBrowser control

Can you specify what failed?

My sample below consists of a form with a WebBrowser and a Button.

The object called y in the end has the sentence "i did it!". So with me it works.

public partial class Form1 : Form
{

public Form1()
{
InitializeComponent();

webBrowser1.DocumentText = @"<html><head>
<script type='text/javascript'>
function doIt() {
alert('hello again');
return 'i did it!';
}
</script>
</head><body>hello!</body></html>";

}

private void button1_Click(object sender, EventArgs e)
{
object y = webBrowser1.Document.InvokeScript("doIt");
}
}

How to call JavaScript inside a WebBrowser control?

Since you are using a WebBrowser object, I will assume that this is actually a Windows forms question and not an asp.net question.

You should look at the InvokeScript function of the web browser.

Let's say your webpage has the following function:

WITHOUT PARAMETERS:

<script type="text/javascript">
// Function Without Parameters
function JavaScriptFunctionWithoutParameters() {
outputID.innerHTML = "JavaScript function called!";
}
</script>

You would want to call it the following way:

this.webBrowser.InvokeScript("JavaScriptFunctionWithoutParameters");

WITH PARAMETERS:

<script type="text/javascript">
// Function With Parameters
function Goto(someParameter) {
outputID.innerHTML = someParameter;
}
</script>

You would call it like this:

object[] param = new object[1];
param [0] = "DM_NEW_OBJECT.ASPX?DM_CAT_ID=2063&DM_PARENT_ID=2217&INPUTSELECTION=&DM_OBJECT_ID=0&PACK_ID=0&CASE_ID=0&mode=0&SITE=Default";
this.webBrowser1.Document.InvokeScript("Goto", param );

how to return javascript function value from webbrowser c#

it is not imposible as @JohnSmith says

With a simple trick you can get the return value from javascript

string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

webBrowser1.DocumentCompleted += (s, e) =>
{
var obj = webBrowser1.Document.InvokeScript("_X_");
//obj will be about:///favicon.ico
//write your code that handles the return value here
};

string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>";

But since we can get the value in DocumentCompleted handler, you can not return it from calling method directly. If you can continue your work, in that method, then no problem. If not, then it needs some more tricks to get it done. Let me know...

UPDATE

Here is full working code, Just invoke TestJavascript somewhere in your form.

async void TestJavascript()
{
string JS_FAVICON = "(function(){links = document.getElementsByTagName('link'); wHref=window.location.protocol + '//' + window.location.hostname + '/favicon.ico'; for(i=0; i<links.length; i++){s=links[i].rel; if(s.indexOf('icon') != -1){ wHref = links[i].href }; }; return wHref; })();";

var retval = await Execute(webBrowser1, JS_FAVICON);
MessageBox.Show(retval.ToString());
}

Task<object> Execute(WebBrowser wb, string anonJsFunc)
{
var tcs = new TaskCompletionSource<object>();
WebBrowserDocumentCompletedEventHandler documentCompleted = null;
documentCompleted = (s, e) =>
{
var obj = wb.Document.InvokeScript("_X_");
tcs.TrySetResult(obj);
wb.DocumentCompleted -= documentCompleted; //detach
};

wb.DocumentCompleted += documentCompleted; //attach
string val = wb.DocumentText = "<script> function _X_(){return " +
anonJsFunc +
";} </script>";

return tcs.Task;
}

How to inject Javascript in WebBrowser control?

For some reason Richard's solution didn't work on my end (insertAdjacentText failed with an exception). This however seems to work:

HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "function sayHello() { alert('hello') }";
head.AppendChild(scriptEl);
webBrowser1.Document.InvokeScript("sayHello");

This answer explains how to get the IHTMLScriptElement interface into your project.

Invoke C# code from JavaScript in a Document in a WebBrowser

What you need to do is set the ObjectForScripting property on the web browser control to an object containing the C# methods you want to call from JavaScript. Then you can access that object from JavaScript using window.external. The only thing to watch out for is that the object has to have the [ComVisibleAttribute(true)] attribute. I've used this successfully for several years.

Here's a page with documenation and a simple example: http://msdn.microsoft.com/en-us/library/a0746166.aspx

Here's the example from the link (I haven't tried this code):

using System;
using System.Windows.Forms;
using System.Security.Permissions;

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
private WebBrowser webBrowser1 = new WebBrowser();
private Button button1 = new Button();

[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}

public Form1()
{
button1.Text = "call script code from client code";
button1.Dock = DockStyle.Top;
button1.Click += new EventHandler(button1_Click);
webBrowser1.Dock = DockStyle.Fill;
Controls.Add(webBrowser1);
Controls.Add(button1);
Load += new EventHandler(Form1_Load);
}

private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.AllowWebBrowserDrop = false;
webBrowser1.IsWebBrowserContextMenuEnabled = false;
webBrowser1.WebBrowserShortcutsEnabled = false;
webBrowser1.ObjectForScripting = this;
// Uncomment the following line when you are finished debugging.
//webBrowser1.ScriptErrorsSuppressed = true;

webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"onclick=\"window.external.Test('called from script code')\">" +
"call client code from script code</button>" +
"</body></html>";
}

public void Test(String message)
{
MessageBox.Show(message, "client code");
}

private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.InvokeScript("test",
new String[] { "called from client code" });
}
}

Error when calling Javascript function located in WPF WebBrowser Control from C# code

Try this:

browser.NavigateToString("<html><script>function callMe() {alert('Hello');} document.myfunc = callMe;</script><body>Hello World</body></html>");
browser.LoadCompleted += (s,e) => browser.InvokeScript("callMe");

How to detect Javascript execution in WebBrowser control

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

How to call and pass arguments to a JavaScript method in a page hosted by the .NET WebBrowser control in C#?

This is a nice example, that I found here:

http://www.codeproject.com/Tips/127356/Calling-JavaScript-function-from-WinForms-and-vice

HTML/JavaScript

<html>
<head>
<script type="text/javascript">
function ShowMessage(message) {
alert(message);
}
function ShowWinFormsMessage() {
var msg = document.getElementById('txtMessage').value;
return window.external.ShowMessage(msg);
}
</script>
</head>
<body>
<input type="text" id="txtMessage" />
<input type="button" value="Show Message" onclick="ShowWinFormsMessage()" />
</body>
</html>

C#

public partial class frmMain : Form {
public frmMain() {
InitializeComponent();
webBrowser1.ObjectForScripting = new ScriptManager(this);
}
private void btnShowMessage_Click(object sender, EventArgs e) {
object[] o = new object[1];
o[0]=txtMessage.Text;
object result = this.webBrowser1.Document.InvokeScript("ShowMessage", o);
}
private void frmMain_Load(object sender, EventArgs e) {
this.webBrowser1.Navigate(@"E:\Projects\2010\WebBrowserJavaScriptExample\WebBrowserJavaScriptExample\TestPage.htm");
}

[ComVisible(true)]
public class ScriptManager {
frmMain _form;
public ScriptManager(frmMain form) {
_form = form;
}
public void ShowMessage(object obj) {
MessageBox.Show(obj.ToString());
}
}
}


Related Topics



Leave a reply



Submit