Yep, this is actually really easy:
CEF.RegisterJsObject() takes two parameters, a name and an object, and exposes the object to all windows using that name in the global scope. This is similar to the ObjectForScripting interface provided by the builtin (IE) WebBrowser control in WinForms. Some differences that I think still apply:
- The IE version lets you use "object" type parameters on the native methods to accept arbitrary values from JS (including things like functions, this boggles my mind), but the CEF version is more strictly typed. I think you can pass out JS objects as Dictionaries, but I tend to find it safer and more convenient to just stick to strings. Unlike regular JS functions, these native functions will throw if you give the wrong type/number of args.
- The IE version exposed properties as well as functions, but I think in CEF only the functions on the object are wrapped, so if you wanted to expose public members or properties, you might need to use plain old get/set methods instead.
By the way, if you want to go the other way and call JS functions from C#, you can do that with the ExecuteScript/EvaluateScript methods.
Those just take strings containing arbitrary JS, and execute them in the window. The evaluate ones do this synchronously, and return the result. To safely concatenate arguments into a string like that, especially string arguments, I like to use JSON encoding to create a JS literal.
Json.NET is a great library for that, if you're using a version of .NET that doesn't include JavaScriptSerializer.