Search code examples
javascript.netinteropv8typescript

JavaScript interoperability with Managed/Native code


I am currently building a server-side application which runs browser-less JavaScript and TypeScript programs. The JavaScript engine I am currently using is Microsoft's JavaScript engine, "Chakra" (however looking at using JavaScript.NET since this hooks into Google's V8 engine in a more elegant manner).

I am programming my application using C# and .NET 4.0 (moving to 4.5 going forward)

So far I have faced a couple of problems, for example, if I run the following:

alert("Hello World");

I get an error because "alert" is undefined. Presumably this is implemented in the browser! (as would other objects such as HTMLElement, XMLHttpRequest etc)

What I want to know is, can I write JavaScript code that marshals code from .NET (or other managed/native systems)

For example:

function alert(message) {
    //Performs call to .NET
    MessageBox.Show("Hello World");
}

NOTES:

I have already done some research here:

Embedding JavaScript engine into .NET

Referencing Google's V8 engine from a .NET app

Javascript engine with good interoperability with JVM and CLR


Solution

  • There are a number of ways to go about this. Chakra is a 'active script engine' in windows, and implements a number of COM interfaces to enable it to tell the OS that it is capable of running script files in an interactive environment.

    One of things this enables, is to use COM (interop if you're pure managed) in your application and offer native objects to the scripting environment. This is how windows script host runs, and enables the WSH class to all script engines that it hosts when you use it to run a script. The COM interface references are on MSDN. You can use IActiveScript::AddNamedItem to expose objects at runtime to the executing script.

    I have done this to enable a hosted IE web browser control to call native code via javascript, but you have to be pretty comfortable in COM's workings and your COM/interop skills have to be pretty keen. In hindsight it was not worth the difficulty of the undertaking, as one of my coworkers found an easier way to accomplish script/host RPC (by watching the navigate event of the browser ccontrol, he was able to craft custom links and then click them programmically and then used the URL from the link to determine which action to undertake, quite a hack but he got it up and running in like 5 minutes and i had spent hours exposing classes to the script runtime...)