0

hi Awesomium browser provide JavaScript execute with result method to return values like this :

private const 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; })();";
string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON); 

however i need to perform this with c# builtin browser how to do it, i think there is method "webBrowser1.Document.InvokeScript" not sure how to use it..

edited... this how Awesomium browser return the value:

private void Awesomium_Windows_Forms_WebControl_DocumentReady(object  sender, UrlEventArgs e)
    {
        // DOM is ready. We can start looking for a favicon.
        //UpdateFavicon();
    }


 private void UpdateFavicon()
    {
        // Execute some simple javascript that will search for a favicon.
        string val = webControl.ExecuteJavascriptWithResult(JS_FAVICON);

        // Check for any errors.
        if (webControl.GetLastError() != Error.None)
            return;

        // Check if we got a valid response.
        if (String.IsNullOrEmpty(val) || !Uri.IsWellFormedUriString(val, UriKind.Absolute))
            return;

        // We do not need to perform the download of the favicon synchronously.
        // May be a full icon set (thus big).
        Task.Factory.StartNew<Icon>(GetFavicon, val).ContinueWith(t =>
        {
            // If the download completed successfully, set the new favicon.
            // This post-completion procedure is executed synchronously.

            if (t.Exception != null)
                return;

            if (t.Result != null)
                this.Icon = t.Result;

            if (this.DockPanel != null)
                this.DockPanel.Refresh();
        },
        TaskScheduler.FromCurrentSynchronizationContext());
    }

    private static Icon GetFavicon(Object href)
    {
        using (WebClient client = new WebClient())
        {
            Byte[] data = client.DownloadData(href.ToString());

            if ((data == null) || (data.Length <= 0))
                return null;

            using (MemoryStream ms = new MemoryStream(data))
            {
                try
                {
                    return new Icon(ms, 16, 16);
                }
                catch (ArgumentException)
                {
                    // May not be an icon file.
                    using (Bitmap b = new Bitmap(ms))
                        return Icon.FromHandle(b.GetHicon());
                }
            }
        }
    }

and this is how i did it with WinForm browser:

 private void webBrowser1_DocumentCompleted(object sender,   WebBrowserDocumentCompletedEventArgs e)
 {
        UpdateFavicon();
 }
 private void UpdateFavicon()
 {
   var obj = webBrowser1.Document.InvokeScript("_X_");
   string val = webBrowser1.DocumentText = "<script> function _X_(){return " + JS_FAVICON + ";} </script>"; 
 }
9
  • Which browser from C# do you mean? Are you using WinForms or WPF or anything else? Commented Sep 1, 2015 at 20:10
  • This has already been answered before: stackoverflow.com/questions/1437251/… Commented Sep 1, 2015 at 20:11
  • i have been searching couldn't find an answer for this sorry Commented Sep 1, 2015 at 20:13
  • @JohnSmith If you think that is the answer, can you post how you would do it with an anonymous javascript function which has no name. Commented Sep 1, 2015 at 20:14
  • It's not possible. You can not invoke anonymous functions. Commented Sep 1, 2015 at 20:15

1 Answer 1

1

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

@jsem And you want me to see your code with my crystall ball and answer it?
@jsem Your code is wrong. In my sample I set first webBrowser1.DocumentText and call InvokeScript in DocumentCompleted event BTW: see my update...
@jsem what is your last comment about? I don't understand anything. I don't know what I can do further. I posted a code ready to copy&paste. If you can't manage it to run it, ignore may answer and I'll delete it.
it keep looping run time error sorry for all trouble i mad

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.