The dotnet project uses Cefsharp and Js to call each other's functions

1. Background

Recently, I used CefSharp to load H5 pages in a project , some of which business logic needs to call Js functions, and Js will also call some native functions:

Here we use the official demo code to add and modify, the modified code is here: DevWiki/CefSharp.MinimalExample - CefSharp.MinimalExample - DevWiki Gitea

2. Js calls Native function

According to the official instructions, General Usage · cefsharp/CefSharp Wiki , divided into two steps:

  1. Set Enable Js
  2. Register a Class for Js to call
//设置 启用 Js
Browser.BrowserSettings.Javascript = CefState.Enabled;
Browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
//注册一个 Class 给Js调用
Browser.JavascriptObjectRepository.Register("script", new Script(), false, BindingOptions.DefaultBinder);

public class Script
{
    
    
    public string GetWindowName()
    {
    
    
        return "MainWindow";
    }

    public void PrintLog(string log)
    {
    
    
        Console.WriteLine($"H5 log:{
      
      log}");
    }
}

For the convenience of testing, set the Browser to respond to F12 to open DevTool:

Browser.WpfKeyboardHandler = new WebBrowserWpfKeyboardHandler(Browser);

public class WebBrowserWpfKeyboardHandler : WpfImeKeyboardHandler
    {
    
    
        public WebBrowserWpfKeyboardHandler(ChromiumWebBrowser owner) : base(owner)
        {
    
    
        }
        public override void HandleKeyPress(KeyEventArgs e)
        {
    
    
            base.HandleKeyPress(e);
            if (e.Key == Key.F12)
            {
    
    
                owner.ShowDevTools();
            }
        }
    }

After running, press F12, open the console input: script.see the prompt:

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-kwCxn2xc-1670731074318)(api/images/iGKYxVbEAHsw/202212102324686.png)]

You can see the functions we registered, so that Js can call native functions.

Another way is to register dynamically, as follows:

Browser.JavascriptObjectRepository.ResolveObject += JavascriptObjectRepositoryOnResolveObject;

private void JavascriptObjectRepositoryOnResolveObject(object sender, JavascriptBindingEventArgs e)
{
    
    
    var repo = e.ObjectRepository;
    if (e.ObjectName == "script")
    {
    
    
        repo.Register("script", new Script(), isAsync: true, options: BindingOptions.DefaultBinder);
    }
}

3. WPF calls Js function

General web pages have alert()this function, that is, a dialog window pops up, press F12 to open devtool, switch to the console, enter the function and press Enter, the result is as follows:

1670728613515.png

You can also pass in a parameter to display a prompt message: alert("test"):

1670728686336.png

So how to call it in the project? According to the official documentation: CefSharp Chinese Help Document cefsharp/CefSharp Wiki

Browser.MainFrame.ExecuteJavaScriptAsync("alert()"); 
// 或者
Browser.ExecuteScriptAsync("alert()");

If you need to pass in parameters, you can use string interpolation directly:

Browser.MainFrame.ExecuteJavaScriptAsync($"alert({message})"); 
// 或者
Browser.ExecuteScriptAsync($"alert({message})");

Or use the method of passing in parameters:

object[] args = new object[2];
args[0] = JsArgs1Tb.Text;
args[1] = JsArgs2Tb.Text;
Browser.ExecuteScriptAsync("alert()", args);

If you install the above code to call the Js function with parameters, it will not actually execute as you expected!

If you install the above code to call the Js function with parameters, it will not actually execute as you expected!

If you install the above code to call the Js function with parameters, it will not actually execute as you expected!

Say important things three times!

Why do the above problems occur? Here we need to look at what the function with parameters does?

    public static void ExecuteScriptAsync(
      this IBrowser browser,
      string methodName,
      params object[] args)
    {
    
    
      string javascriptMethodWithArgs = WebBrowserExtensions.GetScriptForJavascriptMethodWithArgs(methodName, args);
      browser.ExecuteScriptAsync(javascriptMethodWithArgs);
    }

In this code, the function name and function parameters will be spliced ​​first:

WebBrowserExtensions.GetScriptForJavascriptMethodWithArgs(methodName, args);

Here we test alertthe concatenation of functions and parameters:

The result after splicing will be brought automatically (), remove the brackets and test again:

The pop-up window is as follows:

The content that we fill in appears in the prompt.

3. Summary

Use Js to call native functions:

  1. WebBrowser settings enable Js function
  2. Register a class for Js to call

Use native to call js function:

  1. If it is a function without parameters, the function name needs to bring: ()
  2. If it is a function with parameters, either it is spliced ​​into a complete function + parameters when calling, or it is used when calling WebBrowserExtensions.GetScriptForJavascriptMethodWithArgsand the function only writes the name without parentheses.

The above code is in: DevWiki/CefSharp.MinimalExample - CefSharp.MinimalExample - DevWiki Gitea

Guess you like

Origin blog.csdn.net/DevWiki/article/details/128273384