Git Product home page Git Product logo

electron-edge's Introduction

electron-edge

Run .NET and Node.js code in-process on Electron. forked from Edge.js.

It is currently compatible with Electron-v1.6.2 (until node.js v7.4.0)

The usage is same as Edge.js. just replace require('edge') with require('electron-edge'):

-var edge = require('edge');
+var edge = require('electron-edge');

var helloWorld = edge.func(function () {/*
    async (input) => {
        return ".NET Welcomes " + input.ToString();
    }
*/});

Why use electron-edge?

can't load Edge.js module in electron.

because, electron use different version of node.js

you need to install same version of node.js and rebuild edge.js

electron-edge is precompiled edge.js for Electron.

please read this issue: #2

Requirements (Windows)

You must install Visual Studio 2015 redist and .NET framework 4.5.


Edge.js: .NET and Node.js in-process Build Status

NEW Edge.js is now on Slack at https://edgejs.slack.com. Join here.

An edge connects two nodes. This edge connects Node.js and .NET. V8 and CLR/.NET Core/Mono - in process. On Windows, MacOS, and Linux.

image

You can script C# from a Node.js process:

ES5

var edge = require('edge');

var helloWorld = edge.func(function () {/*
    async (input) => { 
        return ".NET Welcomes " + input.ToString(); 
    }
*/});

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

ES6

In ES6 you can use template strings to write multiline C# code.

var edge = require('edge');

var helloWorld = edge.func(`
    async (input) => { 
        return ".NET Welcomes " + input.ToString(); 
    }
`);

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

You can also script Node.js from C#:

using System;
using System.Threading.Tasks;
using EdgeJs;

class Program
{
    public static async Task Start()
    {
        var func = Edge.Func(@"
            return function (data, callback) {
                callback(null, 'Node.js welcomes ' + data);
            }
        ");

        Console.WriteLine(await func(".NET"));
    }

    static void Main(string[] args)
    {
        Start().Wait();
    }
}

What problems does Edge.js solve?

Ah, whatever problem you have. If you have this problem, this solves it.

--Scott Hanselman (@shanselman)

Before you dive in

See the Edge.js overview.
Read the Edge.js introduction on InfoQ.
Listen to the Edge.js podcast on Herdingcode.

image

Contents

Introduction
Scripting CLR from Node.js
    What you need
        Windows
        Linux
        OSX
        Docker
    How to: C# hello, world
    How to: integrate C# code into Node.js code
    How to: specify additional CLR assembly references in C# code
    How to: marshal data between C# and Node.js
    How to: call Node.js from C#
    How to: export C# function to Node.js
    How to: script Python in a Node.js application
    How to: script PowerShell in a Node.js application
    How to: script F# in a Node.js application
    How to: script Lisp in a Node.js application
    How to: script T-SQL in a Node.js application
    How to: support for other CLR languages
    How to: exceptions
    How to: app.config
    How to: debugging
    Performance
    Building on Windows
    Building on OSX
    Building on Linux
    Running tests
Scripting Node.js from CLR
    What you need
    How to: Node.js hello, world
    How to: integrate Node.js into CLR code
    How to: use Node.js built-in modules
    How to: use external Node.js modules
    How to: handle Node.js events in .NET
    How to: expose Node.js state to .NET
    How to: use Node.js in ASP.NET application
    How to: debug Node.js code running in a CLR application
    Building Edge.js NuGet package
    Running tests of scripting Node.js in C#
Use cases and other resources
Contribution and derived work

Introduction

Edge.js allows you to run Node.js and .NET code in one process on Windows, MacOS, and Linux.

You can call .NET functions from Node.js and Node.js functions from .NET. Edge.js takes care of marshalling data between CLR and V8. Edge.js also reconciles threading models of single threaded V8 and multi-threaded CLR. Edge.js ensures correct lifetime of objects on V8 and CLR heaps. The CLR code can be pre-compiled or specified as C#, F#, Python, or PowerShell source: Edge.js can compile CLR scripts at runtime. Edge can be extended to support other CLR languages or DSLs.

Edge.js interop model

Edge.js provides an asynchronous, in-process mechanism for interoperability between Node.js and .NET. You can use this mechanism to:

  • script Node.js from a .NET application (console app, ASP.NET, etc.)
  • script C# from a Node.js application on Windows, MacOS, and Linux
  • access MS SQL from Node.js using ADO.NET more...
  • use CLR multi-threading from Node.js for CPU intensive work more...
  • write native extensions to Node.js in C# instead of C/C++
  • integrate existing .NET components into Node.js applications

Read more about the background and motivations of the project here.

Follow @tjanczuk for updates related to the module.

Scripting CLR from Node.js

If you are writing a Node.js application, this section explains how you include and run CLR code in your app. It works on Windows, MacOS, and Linux.

What you need

Edge.js runs on Windows, Linux, and OSX and requires Node.js 6.x, 5.x, 4.x, 0.12.x, 0.10.x, or 0.8.x, as well as .NET Framework 4.5 (Windows), Mono 4.2.4 (OSX, Linux), or .NET Core 1.0.0 Preview 2 (Windows, OSX, Linux).

NOTE there is a known issue with Mono after 4.2.4 that will be addressed in Mono 4.6.

Windows

If you have both desktop CLR and .NET Core installed, read using .NET Core for how to configure Edge to use one or the other.

image

Linux

image

OSX

  • Node.js 6.x, 5.x, 4.x, 0.12.x, 0.10.x, or 0.8.x
  • Mono 4.2.4 x64 and/or .NET Core
  • Follow OSX setup instructions

image

Docker

Edge.js is available as a Docker image on the tjanczuk/edgejs repository on Docker Hub. The image is based on Debian Trusty, and contains Node.js 6.3.0 x64, Mono 4.2.4 x64, .NET Core 1.0.0 Preview 2 x64 (dotnet-dev-1.0.0-preview2-003121), and Edge.js 6.5.1:

By default Edge uses Mono to execute CLR code:

> docker run -it tjanczuk/edgejs:6.5.1
> cd samples
> node 101_hello_lambda.js
.NET welcomes Node.js

Specify the EDGE_USE_CORECLR=1 environment variable to use .NET Core instead:

> docker run -it tjanczuk/edgejs:6.5.1
> cd samples
> EDGE_USE_CORECLR=1 node 101_hello_lambda.js
.NET welcomes Node.js

Alternatively, you can also specify EDGE_USE_CORECLR when starting the container:

> docker run -it -e EDGE_USE_CORECLR=1 tjanczuk/edgejs:6.5.1

How to: C# hello, world

Follow setup instructions for your platform.

Install edge:

npm install edge

In your server.js:

var edge = require('edge');

var helloWorld = edge.func(function () {/*
    async (input) => { 
        return ".NET Welcomes " + input.ToString(); 
    }
*/});

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

Run and enjoy:

$>node server.js
.NET welcomes JavaScript

If you want to use .NET Core as your runtime and are running in a dual runtime environment (i.e. Windows with .NET 4.5 installed as well or Linux with Mono installed), you will need to tell edge to use .NET Core by setting the EDGE_USE_CORECLR environment variable:

$>EDGE_USE_CORECLR=1 node server.js
.NET Welcomes JavaScript

How to: integrate C# code into Node.js code

Edge provides several ways to integrate C# code into a Node.js application. Regardless of the way you choose, the entry point into the .NET code is normalized to a Func<object,Task<object>> delegate. This allows Node.js code to call .NET asynchronously and avoid blocking the Node.js event loop.

Edge provides a function that accepts a reference to C# code in one of the supported representations, and returns a Node.js function which acts as a JavaScript proxy to the Func<object,Task<object>> .NET delegate:

var edge = require('edge');

var myFunction = edge.func(...);

The function proxy can then be called from Node.js like any asynchronous function:

myFunction('Some input', function (error, result) {
    //...
});

Alternatively, if you know the C# implementation will complete synchronously given the circumstances, you can call this function as any synchronous JavaScript function as follows:

var result = myFunction('Some input', true);

The true parameter instead of a callback indicates that Node.js expects the C# implementation to complete synchronously. If the CLR function implementation does not complete synchronously, the call above will result in an exception.

One representation of CLR code that Edge.js accepts is C# source code. You can embed C# literal representing a .NET async lambda expression implementing the Func<object,Task<object>> delegate directly inside Node.js code:

var add7 = edge.func('async (input) => { return (int)input + 7; }');

In another representation, you can embed multi-line C# source code by providing a function with a body containing a multi-line comment. Edge extracts the C# code from the function body using regular expressions:

var add7 = edge.func(function() {/*
    async (input) => {
        return (int)input + 7;
    }
*/});

Or if you use ES6 you can use template strings to define a multiline string:

var add7 = edge.func(`
    async (input) => {
        return (int)input + 7;
    }
`);

If your C# code is more involved than a simple lambda, you can specify entire class definition. By convention, the class must be named Startup and it must have an Invoke method that matches the Func<object,Task<object>> delegate signature. This method is useful if you need to factor your code into multiple methods:

var add7 = edge.func(function() {/*
    using System.Threading.Tasks;

    public class Startup
    {
        public async Task<object> Invoke(object input)
        {
            int v = (int)input;
            return Helper.AddSeven(v);
        }
    }

    static class Helper
    {
        public static int AddSeven(int v) 
        {
            return v + 7;
        }
    }
*/});

If your C# code grows substantially, it is useful to keep it in a separate file. You can save it to a file with *.csx or *.cs extension, and then reference from your Node.js application:

var add7 = edge.func(require('path').join(__dirname, 'add7.csx'));

If you integrate C# code into your Node.js application by specifying C# source using one of the methods above, edge will compile the code on the fly. If you prefer to pre-compile your C# sources to a CLR assembly, or if your C# component is already pre-compiled, you can reference a CLR assembly from your Node.js code. In the most generic form, you can specify the assembly file name, the type name, and the method name when creating a Node.js proxy to a .NET method:

var clrMethod = edge.func({
    assemblyFile: 'My.Edge.Samples.dll',
    typeName: 'Samples.FooBar.MyType',
    methodName: 'MyMethod' // This must be Func<object,Task<object>>
});

If you don't specify methodName, Invoke is assumed. If you don't specify typeName, a type name is constructed by assuming the class called Startup in the namespace equal to the assembly file name (without the .dll). In the example above, if typeName was not specified, it would default to My.Edge.Samples.Startup.

The assemblyFile is relative to the working directory. If you want to locate your assembly in a fixed location relative to your Node.js application, it is useful to construct the assemblyFile using __dirname. If you are using .NET Core, assemblyFile can also be a project name or NuGet package name that is specified in your project.json or .deps.json dependency manifest.

You can also create Node.js proxies to .NET functions specifying just the assembly name as a parameter:

var clrMethod = edge.func('My.Edge.Samples.dll');

In that case the default typeName of My.Edge.Samples.Startup and methodName of Invoke is assumed as explained above.

How to: specify additional CLR assembly references in C# code

When you provide C# source code and let edge compile it for you at runtime, edge will by default reference only mscorlib.dll and System.dll assemblies. If you're using .NET Core, we automatically reference the most recent versions of the System.Runtime, System.Threading.Tasks, System.Dynamic.Runtime, and the compiler language packages, like Microsoft.CSharp. In applications that require additional assemblies you can specify them in C# code using a special hash pattern, similar to Roslyn. For example, to use ADO.NET you must reference System.Data.dll:

var add7 = edge.func(function() {/*

    #r "System.Data.dll"

    using System.Data;
    using System.Threading.Tasks;

    public class Startup
    {
        public async Task<object> Invoke(object input)
        {
            // ...
        }
    }
*/});

If you prefer, instead of using comments you can specify references by providing options to the edge.func call:

var add7 = edge.func({
    source: function() {/*

        using System.Data;
        using System.Threading.Tasks;

        public class Startup
        {
            public async Task<object> Invoke(object input)
            {
                // ...
            }
        }
    */},
    references: [ 'System.Data.dll' ]
});

If you are using .NET Core and are using the .NET Core SDK and CLI, you must have a project.json file (specification here) that specifies the dependencies for the application. This list of dependencies must also include the Edge.js runtime package and, if you need to be able to dynamically compile your code, the package(s) for the compilers that you plan to use, like Edge.js.CSharp. You must have run the dotnet restore (to restore the dependencies) and dotnet build (to build your project and generate the dependency manifest) commands in that project's directory to generate a .deps.json file under bin/[configuration]/[framework], i.e. bin/Release/netstandard1.6/MyProject.deps.json. This .deps.json file must either be in the current working directory that node is executed in or you must specify its directory by setting the EDGE_APP_ROOT environment variable. For example, if for a netstandard1.6 project in the c:\DotNet\MyProject directory, you would run something like:

set EDGE_APP_ROOT=c:\DotNet\MyProject\bin\Release\netstandard1.6
node app.js

Edge.js also supports running published .NET Core applications on servers that do not have the .NET Core SDK and CLI installed, which is a common scenario in production environments. To do so, the project.json for your application should meet the following requirements:

  1. It should target the netcoreapp1.0 framework moniker.
  2. It should reference Microsoft.NETCore.DotNetHost and Microsoft.NETCore.DotNetHostPolicy. This is required so that the publish process can provide all the native libraries required to create a completely standalone version of your application.
  3. "emitEntryPoint": true should be present under buildOptions. You can add an empty Main() implementation to your project to accomodate it; this method will not be called, but is just a requirement in order for dotnet publish to generate a completely standalone app.

On your development machine, you would run dotnet publish -r [target runtime for your production server] (i.e. dotnet publish -r ubuntu.14.04-x64) to aggregate the package assemblies and native libraries necessary to run your application. You can copy the contents of the publish directory up to your SDK- and CLI-less server and use them directly in Edge.js by setting the EDGE_APP_ROOT environment variable to the directory on the server that you copied the published application to.

How to: marshal data between C# and Node.js

Edge.js can marshal any JSON-serializable value between .NET and Node.js (although JSON serialization is not used in the process). Edge also supports marshalling between Node.js Buffer instance and a CLR byte[] array to help you efficiently pass binary data.

You can call .NET from Node.js and pass in a complex JavaScript object as follows:

var dotNetFunction = edge.func('Edge.Sample.dll');

var payload = {
    anInteger: 1,
    aNumber: 3.1415,
    aString: 'foo',
    aBoolean: true,
    aBuffer: new Buffer(10),
    anArray: [ 1, 'foo' ],
    anObject: { a: 'foo', b: 12 }
};

dotNetFunction(payload, function (error, result) { });

In .NET, JavaScript objects are represented as dynamics (which can be cast to IDictionary<string,object> if desired), JavaScript arrays as object[], and JavaScript Buffer as byte[]. Scalar JavaScript values have their corresponding .NET types (int, double, bool, string). Here is how you can access the data in .NET:

using System.Threading.Tasks;

public class Startup
{
    public async Task<object> Invoke(dynamic input)
    {
        int anInteger = (int)input.anInteger;
        double aNumber = (double)input.aNumber;
        string aString = (string)input.aString;
        bool aBoolean = (bool)input.aBoolean;
        byte[] aBuffer = (byte[])input.aBuffer;
        object[] anArray = (object[])input.anArray;
        dynamic anObject = (dynamic)input.anObject;

        return null;
    }
}

Similar type marshalling is applied when .NET code passes data back to Node.js code. In .NET code you can provide an instance of any CLR type that would normally be JSON serializable, including domain specific types like Person or anonymous objects. For example:

using System.Threading.Tasks;

public class Person
{
    public int anInteger = 1;
    public double aNumber = 3.1415;
    public string aString = "foo";
    public bool aBoolean = true;
    public byte[] aBuffer = new byte[10];
    public object[] anArray = new object[] { 1, "foo" };
    public object anObject = new { a = "foo", b = 12 };
}

public class Startup
{
    public async Task<object> Invoke(dynamic input)
    {
        Person person = new Person();
        return person;
    }
}

In your Node.js code that invokes this .NET method you can display the result object that the callback method receives:

var edge = require('edge');

var getPerson = edge.func(function () {/*
    using System.Threading.Tasks;

    public class Person
    {
        public int anInteger = 1;
        public double aNumber = 3.1415;
        public string aString = "foo";
        public bool aBoolean = true;
        public byte[] aBuffer = new byte[10];
        public object[] anArray = new object[] { 1, "foo" };
        public object anObject = new { a = "foo", b = 12 };
    }

    public class Startup
    {
        public async Task<object> Invoke(dynamic input)
        {
            Person person = new Person();
            return person;
        }
    }
*/});

getPerson(null, function (error, result) {
    if (error) throw error;
    console.log(result);
});

Passing this .NET object to Node.js generates a JavaScript object as follows:

$>node sample.js
{ anInteger: 1,
  aNumber: 3.1415,
  aString: 'foo',
  aBoolean: true,
  aBuffer: <Buffer 00 00 00 00 00 00 00 00 00 00>,
  anArray: [ 1, 'foo' ],
  anObject: { a: 'foo', b: 12 } }

When data is marshalled from .NET to Node.js, no checks for circular references are made. They will typically result in stack overflows. Make sure the object graph you are passing from .NET to Node.js is a tree and does not contain any cycles.

WINDOWS ONLY When marshalling strongly typed objects (e.g. Person) from .NET to Node.js, you can optionally tell Edge.js to observe the System.Web.Script.Serialization.ScriptIgnoreAttribute. You opt in to this behavior by setting the EDGE_ENABLE_SCRIPTIGNOREATTRIBUTE environment variable:

set EDGE_ENABLE_SCRIPTIGNOREATTRIBUTE=1

Edge.js by default does not observe the ScriptIgnoreAttribute to avoid the associated performance cost.

How to: call Node.js from C#

In addition to marshalling data, edge can marshal proxies to JavaScript functions when invoking .NET code from Node.js. This allows .NET code to call back into Node.js.

Suppose the Node.js application passes an add function to the .NET code as a property of an object. The function receives two numbers and returns the sum of them via the provided callback:

var edge = require('edge');

var addAndMultiplyBy2 = edge.func(function () {/*
    async (dynamic input) => {
        var add = (Func<object, Task<object>>)input.add;
        var twoNumbers = new { a = (int)input.a, b = (int)input.b };
        var addResult = (int)await add(twoNumbers);
        return addResult * 2;
    }   
*/});

var payload = {
    a: 2,
    b: 3,
    add: function (data, callback) {
        callback(null, data.a + data.b);
    }
};

addAndMultiplyBy2(payload, function (error, result) {
    if (error) throw error;
    console.log(result);
});

The .NET code implements the addAndMultiplyBy2 function. It extracts the two numbers passed from Node.js, calls back into the add function exported from Node.js to add them, multiplies the result by 2 in .NET, and returns the result back to Node.js:

$>node sample.js
10

The Node.js function exported from Node.js to .NET must follow the prescriptive async pattern of accepting two parameters: payload and a callback. The callback function accepts two parameters. The first one is the error, if any, and the second the result of the operation:

function (payload, callback) {
    var error;  // must be null or undefined in the absence of error
    var result; 

    // do something

    callback(error, result);
}

The proxy to that function in .NET has the following signature:

Func<object,Task<object>>

Using TPL in CLR to provide a proxy to an asynchronous Node.js function allows the .NET code to use the convenience of the await keyword when invoking the Node.js functionality. The example above shows the use of the await keyword when calling the proxy of the Node.js add method.

How to: export C# function to Node.js

Similarly to marshalling functions from Node.js to .NET, Edge.js can also marshal functions from .NET to Node.js. The .NET code can export a Func<object,Task<object>> delegate to Node.js as part of the return value of a .NET method invocation. For example:

var createHello = edge.func(function () {/*
    async (input) =>
    {
        return (Func<object,Task<object>>)(async (i) => { 
            Console.WriteLine("Hello from .NET"); 
            return null; 
        });
    }
*/});

var hello = createHello(null, true); 
hello(null, true); // prints out "Hello from .NET"

This mechanism in conjunction with a closure can be used to expose CLR class instances or CLR state in general to JavaScript. For example:

var createCounter = edge.func(function () {/*
    async (input) =>
    {
        var k = (int)input; 
        return (Func<object,Task<object>>)(async (i) => { return ++k; });
    }
*/});

var counter = createCounter(12, true); // create counter with 12 as initial state
console.log(counter(null, true)); // prints 13
console.log(counter(null, true)); // prints 14

How to: script Python in a Node.js application

NOTE This functionality requires IronPython and has been tested on Windows only.

Edge.js enables you to run Python and Node.js in-process.

In addition to platform specific prerequisites you need IronPython 2.7.3 to proceed.

Hello, world

Install edge and edge-py modules:

npm install edge
npm install edge-py

In your server.js:

var edge = require('edge');

var hello = edge.func('py', function () {/*
    def hello(input):
        return "Python welcomes " + input

    lambda x: hello(x)
*/});

hello('Node.js', function (error, result) {
    if (error) throw error;
    console.log(result);
});

Run and enjoy:

$>node py.js
Python welcomes Node.js

The interop model

Your Python script must evaluate to a lambda expression that accepts a single parameter. The parameter represents marshalled input from the Node.js code. The return value of the lambda expression is passed back as the result to Node.js code. The Python script can contain constructs (e.g. Python functions) that are used in the closure of the lambda expression. The instance of the script with associated state is created when edge.func is called in Node.js. Each call to the function referes to that instance.

The simplest echo Python script you can embed in Node.js looks like this:

lambda x: x

To say hello, you can use something like this:

lambda: x: "Hello, " + x

To maintain a running sum of numbers:

current = 0

def add(x):
    global current
    current = current + x
    return current

lambda x: add(x)

Python in its own file

You can reference Python script stored in a *.py file instead of embedding Python code in a Node.js script.

In your hello.py file:

def hello(input):
    return "Python welcomes " + input

lambda x: hello(x)

In your hello.js file:

var edge = require('edge');

var hello = edge.func('py', 'hello.py');

hello('Node.js', function (error, result) {
    if (error) throw error;
    console.log(result);
});

Run and enjoy:

$>node hello.js
Python welcomes Node.js

To sync or to async, that is the question

In the examples above Python script was executing asynchronously on its own thread without blocking the singleton V8 thread on which the Node.js event loop runs. This means your Node.js application remains responsive while the Python code executes in the background.

If you know your Python code is non-blocking, or if you know what you are doing, you can tell Edge.js to execute Python code on the singleton V8 thread. This will improve performance for non-blocking Python scripts embedded in a Node.js application:

var edge = require('edge');

var hello = edge.func('py', {
    source: function () {/*
        def hello(input):
            return "Python welcomes " + input

        lambda x: hello(x)
    */},
    sync: true
});

console.log(hello('Node.js', true));

The sync: true property in the call to edge.func tells Edge.js to execute Python code on the V8 thread as opposed to creating a new thread to run Python script on. The true parameter in the call to hello requests that Edge.js does in fact call the hello function synchronously, i.e. return the result as opposed to calling a callback function.

How to: script PowerShell in a Node.js application

NOTE This functionality only works on Windows.

Edge.js enables you to run PowerShell and Node.js in-process on Windows. Edge-PS connects the PowerShell ecosystem with Node.js.

You need Windows, Node.js, .NET 4.5, and PowerShell 3.0 to proceed.

Hello, world

Install edge and edge-ps modules:

npm install edge
npm install edge-ps

In your server.js:

var edge = require('edge');

var hello = edge.func('ps', function () {/*
"PowerShell welcomes $inputFromJS on $(Get-Date)"
*/});

hello('Node.js', function (error, result) {
    if (error) throw error;
    console.log(result[0]);
});

Run and enjoy:

C:\testEdgeps>node server
PowerShell welcomes Node.js on 05/04/2013 09:38:40

Tapping into PowerShell's ecosystem

Rather than embedding PowerShell directly, you can use PowerShell files, dot source them and even use Import-Module.

What you can do in native PowerShell works in Node.js.

Interop PowerShell and Python

Here you can reach out to IronPython from PowerShell from within Node.js on Windows. This holds true for working with JavaScript frameworks and C#.

var edge = require('edge');

var helloPowerShell = edge.func('ps', function () {/*
	"PowerShell welcomes $inputFromJS"
*/});

var helloPython = edge.func('py', function () {/*
    def hello(input):
        return "Python welcomes " + input

    lambda x: hello(x)
*/});


helloPython('Node.js', function(error, result){
	if(error) throw error;

	helloPowerShell(result, function(error, result){
		if(error) throw error;
		console.log(result[0]);
	});
});

How to: script F# in a Node.js application

NOTE This functionality has not been tested on non-Windows platforms.

This section is coming up. In the meantime please refer to Dave Thomas blog post. This has been validated on Windows only.

var edge = require('edge');

var helloFs = edge.func('fs', function () {/*
    fun input -> async { 
        return "F# welcomes " + input.ToString()
    }
*/});

helloFs('Node.js', function (error, result) {
    if (error) throw error;
    console.log(result);
});

How to: script Lisp in a Node.js application

NOTE This functionality has not been tested on non-Windows platforms.

The edge-lsharp extension uses LSharp to compile and run Lisp to .NET.

Install edge and edge-lsharp modules:

npm install edge
npm install edge-lsharp

In your server.js:

var edge = require('edge');
var fact = edge.func('lsharp', function(){/*

;; Factorial
(def fact(n) 
    (if (is n 0) 1 (* n (fact (- n 1)))))

*/});

fact([5], function(err, answer){
    console.log(answer);
    // = 120
});

An LSharp filename can be passed in instead of the Lisp string/comment:

var edge = require('edge');
var lisp = edge.func('lsharp', 'lisp-func.ls');

lisp(['arg1', 'arg2'], function(err, result){
    
});

In Lisp you can specify either a function (as shown in the first example) or just return a value:

var edge = require('edge');
var lisp = edge.func('lsharp', '(+ 2 3)');

lisp([], function(err, answer){
    console.log(answer);
    // = 5
});

How to: script T-SQL in a Node.js application

NOTE This functionality has only been tested on Windows. Although ADO.NET exist in Mono, your mileage can vary.

The edge-sql extension of Edge.js allows for accessing MS SQL databases by scripting T-SQL inside the Node.js application. The edge-sql extension uses async ADO.NET SQL client to access MS SQL.

You need Windows, Node.js, and .NET 4.5. To run the sample code below you also need a connection string to the sample Northwind database that ships with MS SQL.

Hello, world

Install edge and edge-sql modules:

npm install edge
npm install edge-sql

Set the connection string as an environment variable (your connection string may be different):

set EDGE_SQL_CONNECTION_STRING=Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True

In your server.js:

var edge = require('edge');

var getTop10Products = edge.func('sql', function () {/*
    select top 10 * from Products
*/});

getTop10Products(null, function (error, result) {
    if (error) throw error;
    console.log(result);
    console.log(result[0].ProductName);
    console.log(result[1].ReorderLevel);
});

Run and enjoy:

C:\projects\edge\samples>node server.js
[ { ProductID: 10,
    ProductName: 'New Ikura',
    SupplierID: 4,
    CategoryID: 8,
    QuantityPerUnit: '12 - 200 ml jars',
    UnitPrice: '31.000',
    UnitsInStock: 31,
    UnitsOnOrder: 0,
    ReorderLevel: 0,
    Discontinued: false },
    ...
]
New Ikura
12

Parameterized queries

You can construct a parameterized query once and provide parameter values on a per-call basis:

var edge = require('edge');

var getProduct = edge.func('sql', function () {/*
    select * from Products 
    where ProductId = @myProductId
*/});

getProduct({ myProductId: 10 }, function (error, result) {
    if (error) throw error;
    console.log(result);
});

Basic CRUD support: select, update, insert, delete

The four basic CRUD operations are supported. For example, here is how an update can look like:

var edge = require('edge');

var updateProductName = edge.func('sql', function () {/*
    update Products
    set ProductName = @newName 
    where ProductId = @myProductId
*/});

updateProductName({ myProductId: 10, newName: 'New Ikura' }, function (error, result) {
    if (error) throw error;
    console.log(result);
});

How to: support for other CLR languages

Edge.js can work with any pre-compiled CLR assembly that contains the Func<object,Task<object>> delegate. Out of the box, Edge.js also allows you to embed C# source code in a Node.js application and compile it on the fly.

To enable compilation of other CLR languages (e.g. F#) at runtime, or to support domain specific languages (DSLs) like T-SQL, you can use the compiler composability model provided by Edge.js. Please read the add support for a CLR language guide to get started.

How to: exceptions

Edge.js marshals Node.js errors and exceptions to .NET as well as .NET exceptions to Node.js.

CLR exceptions thrown in .NET code invoked from Node.js are marshalled as the error parameter to the Node.js callback function. Consider this example:

var edge = require('edge');

var clrFunc = edge.func(function () {/*
    async (dynamic input) => {
        throw new Exception("Sample exception");
    }
*/});

clrFunc(null, function (error, result) {
    if (error) {
		console.log('Is Error?', error instanceof Error);
		console.log('-----------------');
		console.log(util.inspect(error, showHidden=true, depth=99, colorize=false));
		return;
	}
});

Running this Node.js application shows that the CLR exception was indeed received by the Node.js callback. The error parameter contains an Error object having most of the properties of the Exceptions copied over:

Is Error? true
-----------------
{ [System.AggregateException: One or more errors occurred.]
  message: 'One or more errors occurred.',
  name: 'System.AggregateException',
  InnerExceptions: 'System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]',
  Message: 'One or more errors occurred.',
  Data: 'System.Collections.ListDictionaryInternal',
  InnerException:
   { [System.Exception: Sample exception]
     message: 'Sample exception',
     name: 'System.Exception',
     Message: 'Sample exception',
     Data: 'System.Collections.ListDictionaryInternal',
     TargetSite: 'System.Reflection.RuntimeMethodInfo',
     StackTrace: '   at Startup.<<Invoke>b__0>d__2.MoveNext() in c:\\Users\\User.Name\\Source\\Repos\\eCash2\\test\\edge2.js:line 7\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at Startup.<Invoke>d__4.MoveNext() in c:\\Users\\User.Name\\Source\\Repos\\eCash2\\test\\edge2.js:line 5',
     Source: 'cp2luegt',
     HResult: -2146233088 },
  HResult: -2146233088 }

The exception is copied back as Error object like every normal result object from the .NET world to JavaScript. Therefore all properties and their values are available on the Error object.

Additionally, the following happens during the mapping:

  • To represent the Exception type, its full name is stored as name.
  • To follow the JavaScript convention for Errors, the Message is also stored as the property message.
  • System::Reflection::RuntimeMethodInfos are not copied to avoid stack overflows
$>node sample.js

Edge.js:58
    edge.callClrFunc(appId, data, callback);
                     ^
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. 
---> System.Exception: Sample exception
   at Startup.Invoke(Object input) in sample.cs:line 12

JavaScript exceptions thrown in Node.js code invoked from .NET are wrapped in a CLR exception and cause the asynchronous Task<object> to complete with a failure. Errors passed by Node.js code invoked from .NET code to the callback function's error parameter have the same effect. Consider this example:

var edge = require('edge');

var multiplyBy2 = edge.func(function () {/*
    async (dynamic input) => {
        var aFunctionThatThrows = (Func<object, Task<object>>)input.aFunctionThatThrows;
        try {
            var aResult = await aFunctionThatThrows(null);
        }
        catch(Exception e)
        {
            Console.WriteLine(e);
        }

        return null;
    }
*/});

var payload = {
    someParameter: 'arbitrary parameter',
    aFunctionThatThrows: function (data, callback) {
        throw new Error('Sample JavaScript error');
    }
};

multiplyBy2(payload, function (error, result) {
    if (error) throw error;
    console.log(result);
});

Running the code shows the .NET code receiving a CLR exception as a result of the Node.js function throwing a JavaScript error. The exception shows the complete stack trace, including the part that executed in the Node.js code:

$>node sample.js
System.Exception: Error: Sample JavaScript error
    at payload.aFunctionThatThrows (sample.js:7:11)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Edge.Sample.Startup.<Invoke>d__0.MoveNext()

How to: app.config

When running C# code within Node.js app, the app config file is node.exe.config and should be located right next to the node.exe file.

How to: debugging

NOTE This is Windows-only functionality.

On Windows, you can debug the .NET code running as part of your Node.js application by attaching a managed code debugger (e.g. Visual Studio) to node.exe. You can debug .NET code in a pre-compiled CLR assembly as well C# literals embedded in the application and compiled by Edge.js at runtime.

Debugging pre-compiled .NET code

If you have integrated .NET code into a Node.js application using a pre-compiled CLR assembly like this:

var hello = edge.func('My.Assembly.dll');

then the best way to debug your .NET code is to attach a managed code debugger (e.g. Visual Studio) to the node.exe process. Since the node.exe process runs both native and managed code, make sure to select managed code type as target:

debug

From there, you can set breakpoints in your .NET code and the debugger will stop when they are reached.

Debugging embedded C# code

Debugging embedded C# code (on Windows) requires that EDGE_CS_DEBUG environment variable is set in the environment of the node.exe process:

set EDGE_CS_DEBUG=1

Without this setting (the default), Edge.js will not generate debugging information when compiling embedded C# code.

You can debug C# code embedded into a Node.js application using a reference to a *.cs or *.csx file:

var hello = edge.func('MyClass.cs');

You can also debug C# code embedded directly into a *.js file using the function comment syntax:

var hello = edge.func(function () {/*
    async (input) =>
    {
        System.Diagnostics.Debugger.Break();
        var result = ".NET welcomes " + input.ToString();
        return result;
    }
*/});

You cannot debug C# code embedded as a simple string literal:

var hello = edge.func('async (input) => { return 2 * (int)input; }');

After setting EDGE_CS_DEBUG=1 environment variable before starting node.exe and attaching the managed debugger to the node.exe process, you can set breakpoints in C# code (which may appear as a JavaScript comment), or use System.Diagnostics.Debugger.Break() to break into the debugger from .NET code.

debug-inline

Performance

Read more about performance of Edge.js on the wiki. Here is the gist of the latency (smaller is better):

edgejs-performance1

Building on Windows

You must have Visual Studio 2015 toolset, Python 2.7.x, and node-gyp installed for building.

To build and test the project against all supported versions of Node.js in x86 and x64 flavors, run the following:

tools\buildall.bat
test\testall.bat
npm run jshint

To build one of the versions of Node.js officially released by Node.js, do the following:

cd tools
build.bat release 6.4.0

Note: the Node.js version number you provide must be version number corresponding to one of the subdirectories of http://nodejs.org/dist. The command will build both x32 and x64 architectures (assuming you use x64 machine). The command will also copy the edge_*.node executables to appropriate locations under lib\native directory where they are looked up from at runtime. The npm install step copies the C standard library shared DLL to the location of the edge_*.node files for the component to be ready to go.

To build the C++\CLI native extension using the version of Node.js installed on your machine, issue the following command:

npm install -g node-gyp
node-gyp configure --msvs_version=2015
node-gyp build -debug

You can then set the EDGE_NATIVE environment variable to the fully qualified file name of the built edge_*.node binary (edge_nativeclr.node if you're using the native CLR runtime or edge_coreclr.node if you're using .NET Core). It is useful during development, for example:

set EDGE_NATIVE=C:\projects\edge\build\Debug\edge_nativeclr.node

You can also set the EDGE_DEBUG environment variable to 1 to have the edge module generate debug traces to the console when it runs.

Running tests

You must have mocha installed on the system. Then:

npm test

or, from the root of the enlistment:

mocha -R spec

NOTE in environments with both desktop CLR/Mono and .NET Core installed, tests will by default use desktop CLR/Mono. To run tests against .NET Core, use:

EDGE_USE_CORECLR=1 npm test

Node.js version targeting on Windows

NOTE this is Windows only functionality.

If you want to run tests after building against a specific version of Node.js that one of the previous builds used, issue the following command:

cd test
test.bat ia32 0.10.0

Which will run the tests using Node.js x86 v0.10.0. Similarly:

cd test
test.bat x64 0.8.22

Would run tests against Node.js 0.8.22 on x64 architecture.

Lastly, you can run jshint on the project with:

npm run jshint

Building on OSX

Prerequisities:

You can use Edge.js on OSX with either Mono or .NET Core installed, or both.

If you choose to install Mono, select the universal installer to make sure you get the x64 version. Edge.js requires Mono x64. If you choose to install .NET Core, follow the steps here

Then install and build Edge.js:

brew install pkg-config
npm install edge

NOTE if the build process complains about being unable to locate Mono libraries, you may need to specify the search path explicitly. This may be installation dependent, but in most cases will look like:

PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig \
  npm install edge

If you installed both Mono and .NET Core, by default Edge will use Mono. You opt in to using .NET Core with the EDGE_USE_CORECLR environment variable:

EDGE_USE_CORECLR=1 node myapp.js

Building on OSX (advanced)

To build edge from a clone of the repository or source code:

node-gyp configure build

To build a debug build instead of release, you need to:

node-gyp configure build -debug
export EDGE_NATIVE=/Users/tomek/edge/build/Debug/edge_nativeclr.node

Building on Linux

For a normative set of steps to set up Edge.js on Linux with both Mono and CoreCLR please refer to the Dockerfile. You can also use the ready-made Docker image.

Using .NET Core

If you have only .NET Core installed on your system and not Mono, you can run Edge with no changes. However, if you have both runtimes installed, Edge will automatically use Mono unless directed otherwise. To use .NET Core in a dual-runtime environment, set the EDGE_USE_CORECLR=1 environment variable when starting node, i.e.

EDGE_USE_CORECLR=1 node sample.js

Edge will try to find the .NET Core runtime in the following locations:

  • The path in the CORECLR_DIR environment variable, if provided
  • The current directory
  • The directory containing edge_*.node
  • Directories in the PATH environment variable. Once a directory containing the dotnet executable is located, we then do the following to decide which version of the framework (you can have several installed at once) to load
    • If the CORECLR_VERSION environment variable was specified, we try to load that version
    • Else, if the project.json/*.deps.json has a reference to Microsoft.NETCore.App, indicating that it was built for a specific framework version, we try to load that version
    • Otherwise, we pick the maximum installed version

So, if the CLR is another location or you want to use a version of the CLR other than the default that you've set, the best way to specify that is through the CORECLR_DIR or CORECLR_VERSION environment variables, i.e.

EDGE_USE_CORECLR=1 \
CORECLR_DIR=/usr/share/dotnet/dnx-coreclr-linux-x64.1.0.0-beta6-11944 \
node sample.js

Scripting Node.js from CLR

If you are writing a CLR application (e.g. a C# console application or ASP.NET web app), this section explains how you include and run Node.js code in your app. Currently it works on Windows using desktop CLR, but support for MacOS, and Linux as well as .NET Core is coming soon.

What you need

You need Windows with:

Edge.js support for scripting Node.js ships as a NuGet Package called Edge.js. It comes with everything you need to get started writing applications for x86 and x64 architectures. However, if you want to use additional Node.js packages from NPM, you must separately install Node.js runtime to access the NPM package manager. Edge.js NuGet package has been developed and tested with Node.js v6.5.0. Older Edge.js packages exist for prior versions of Node.js. If you choose a different version of Node.js to install NPM packages, your mileage can vary.

NOTE you cannot use native Node.js extensions when scripting Node.js from CLR using Edge.

You can install the Edge.js NuGet package using the Visual Studio built-in NuGet package management functionality or using the stand-alone NuGet client.

How to: Node.js hello, world

Create a .NET 4.5 Console Application in Visual Studio. Add the Edge.js NuGet package to the project. Then in your code:

using System;
using System.Threading.Tasks;
using EdgeJs;

class Program
{
    public static async Task Start()
    {
        var func = Edge.Func(@"
            return function (data, callback) {
                callback(null, 'Node.js welcomes ' + data);
            }
        ");

        Console.WriteLine(await func(".NET"));
    }

    static void Main(string[] args)
    {
        Start().Wait();
    }
}

Compile and run:

C:\project\sample\bin\Debug> sample.exe
Node.js welcomes .NET

How to: integrate Node.js code into CLR code

The Edge.js NuGet package contains a single managed assembly EdgeJs.dll with a single class EdgeJs.Edge exposing a single static function Func. The function accepts a string containing code in Node.js that constructs and returns a JavaScript function. The JavaScript function must have the signature required by Edge.js's prescriptive interop pattern: it must accept one parameter and a callback, and the callback must be called with an error and one return value:

var func = Edge.Func(@"
    return function (data, callback) {
        callback(null, 'Hello, ' + data);
    }
");

Edge.js creates a Func<object,Task<object>> delegate in CLR that allows .NET code to call the Node.js function asynchronously. You can use the standard TPL mechanisms or the async/await keywords to conveniently await completion of the asynchornous Node.js function:

var result = await func(".NET");
// result == "Hello, .NET"

Note that the Node.js code snippet is not a function definition. Instead it must create and return a function instance. This allows you to initialize and maintain encapsulated Node.js state associated with the instance of the created function. The initialization code will execute only once when you call Edge.Func. Conceptually this is similar to defining a Node.js module that exports a single function (by returning it to the caller). For example:

var increment = Edge.Func(@"
    var current = 0;

    return function (data, callback) {
        current += data;
        callback(null, current);
    }
");

Console.WriteLine(await increment(4)); // outputs 4
Console.WriteLine(await increment(7)); // outputs 11

Using multiline C# string literals is convenient for short Node.js code snippets, but you may want to store larger Node.js code in its own *.js file or files.

One pattern is to store your Node.js code in a myfunc.js file:

return function (data, callback) {
    callback(null, 'Node.js welcomes ' + data);
}

And then load such file into memory with File:

var func = Edge.Func(File.ReadAllText("myfunc.js"));

Another pattern is to define a Node.js module that itself is a function:

module.exports = function (data, callback) {
    callback(null, 'Node.js welcomes ' + data);
};

And then load and return this module with a short snippet of Node.js:

var func = Edge.Func(@"return require('./../myfunc.js')");

(Note the relative location of the file).

How to: use Node.js built-in modules

You can use Node.js built-in modules out of the box. For example, you can set up a Node.js HTTP server hosted in a .NET application and call it from C#:

var createHttpServer = Edge.Func(@"
    var http = require('http');

    return function (port, cb) {
        var server = http.createServer(function (req, res) {
            res.end('Hello, world! ' + new Date());
        }).listen(port, cb);
    };
");

await createHttpServer(8080);
Console.WriteLine(await new WebClient().DownloadStringTaskAsync("http://localhost:8080"));

How to: use external Node.js modules

You can use external Node.js modules, for example modules installed from NPM.

Note: Most Node.js modules are written in JavaScript and will execute in Edge as-is. However, some Node.js external modules are native binary modules, rebuilt by NPM on module installation to suit your local execution environment. Native binary modules will not run in Edge unless they are rebuilt to link against the NodeJS dll that Edge uses.

To install modules from NPM, you must first install Node.js on your machine and use the npm package manager that comes with the Node.js installation. NPM modules must be installed in the directory where your build system places the Edge.js NuGet package (most likely the same location as the rest of your application binaries), or any ancestor directory. Alternatively, you can install NPM modules globally on the machine using npm install -g:

C:\projects\websockets> npm install ws
...
[email protected] node_modules\ws
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

You can then use the installed ws module to create a WebSocket server inside of a .NET application:

class Program
{
    public static async void Start()
    {
        var createWebSocketServer = Edge.Func(@"
            var WebSocketServer = require('ws').Server;

            return function (port, cb) {
                var wss = new WebSocketServer({ port: port });
                wss.on('connection', function (ws) {
                    ws.on('message', function (message) {
                        ws.send(message.toUpperCase());
                    });
                    ws.send('Hello!');
                });
                cb();
            };
        ");

        await createWebSocketServer(8080);
    }

    static void Main(string[] args)
    {
        Task.Run((Action)Start);
        new ManualResetEvent(false).WaitOne();
    }
}

This WebSocket server sends a Hello message to the client when a new connection is established, and then echos a capitalized version of every message it receives back to the client. You can test this webserver with the wscat tool included with the ws module. To make it convenient to use, first install the ws module globally:

npm install ws -g

Then start the .NET application conatining the WebSocket server and establish a connection to it with wscat:

C:\projects\websockets> wscat -c ws://localhost:8080/

connected (press CTRL+C to quit)

< Hello!
> foo
< FOO
> bar
< BAR

A self-contained Node.js WebSocket server, even if running within a .NET application, is rather unexciting. After all, the same could be accomplished with a stand-alone Node.js process. Ideally you could extablish a WebSocket server in Node.js, but handle the messages in .NET. Let's do it - read on.

How to: handle Node.js events in .NET

It is often useful to handle certain events raised by the Node.js code within .NET. For example, you may want to establish a WebSocket server in Node.js, and handle the incoming messages in the .NET part of your application. This can be accomplished by passig a .NET callback function to Node.js when the the WebSocket server is created:

class Program
{
    public static async void Start()
    {
        // Define an event handler to be called for every message from the client

        var onMessage = (Func<object, Task<object>>)(async (message) =>
        {
            return "Received string of length " + ((string)message).Length;
        });

        // The WebSocket server delegates handling of messages from clients
        // to the supplied .NET handler

        var createWebSocketServer = Edge.Func(@"
            var WebSocketServer = require('ws').Server;

            return function (options, cb) {
                var wss = new WebSocketServer({ port: options.port });
                wss.on('connection', function (ws) {
                    ws.on('message', function (message) {
                        options.onMessage(message, function (error, result) {
                            if (error) throw error;
                            ws.send(result);
                        });
                    });
                    ws.send('Hello!');
                });
                cb();
            };
        ");

        // Create a WebSocket server on a specific TCP port and using the .NET event handler

        await createWebSocketServer(new
        {
            port = 8080,
            onMessage = onMessage
        });
    }

    static void Main(string[] args)
    {
        Task.Run((Action)Start);
        new ManualResetEvent(false).WaitOne();
    }
}

Using wscat, you can verify the .NET handler is indeed invoked for every websocket message:

C:\projects\websockets> wscat -c ws://localhost:8080/

connected (press CTRL+C to quit)

< Hello!
> Foo
< Received string of length 3
> FooBar
< Received string of length 6

This example shows how Edge.js can create JavaScript proxies to .NET functions and marshal calls across the V8/CLR boundary in-process. Read more about data marshaling between Node.js and CLR.

How to: expose Node.js state to .NET

In the previous example a Node.js HTTP server was created and started from .NET. Suppose at some point you want to stop the HTTP server from your .NET code. Given that all references to it are embedded within Node.js code, it is not possible. However, just as Edge.js can pass a .NET function to Node.js, it also can export a Node.js function to .NET. Moreover, that function can be implemented as a closure over Node.js state. This is how it would work:

var createHttpServer = Edge.Func(@"
    var http = require('http');

    return function (port, cb) {
        var server = http.createServer(function (req, res) {
            res.end('Hello, world! ' + new Date());
        }).listen(port, function (error) {
            cb(error, function (data, cb) {
                server.close();
                cb();
            });
        });
    };
");

var closeHttpServer = (Func<object,Task<object>>)await createHttpServer(8080);
Console.WriteLine(await new WebClient().DownloadStringTaskAsync("http://localhost:8080"));
await closeHttpServer(null);

Notice how the createHttpServer function, in addition to starting an HTTP server in Node.js, is also returning a .NET proxy to a JavaScript function that allows that server to be stopped.

How to: use Node.js in ASP.NET web applications

Using Node.js via Edge.js in ASP.NET web applications is no different than in a .NET console application. The Edge.js NuGet package must be referenced in your ASP.NET web application. If you are using any external Node.js modules, the entire node_modules subdirectory structure must be binplaced to the bin folder of you web application, and deployed that way to the server.

How to: debug Node.js code running in a CLR application

The EDGE_NODE_PARAMS environment variable allows you to specify any options that are normally passed via command line to the node executable. This includes the --debug options necessary to use node-inspector to debug Node.js code.

Building Edge.js NuGet package

Note This mechanism requires hardening, expect the road ahead to be bumpy.

These are unstructions for building the Edge.js NuGet package on Windows. The package will support running apps in both x86 and x64 architectures using a selected version of Node.js. The resulting NuGet package is all-inclusive with the only dependency being .NET 4.5.

Preprequisties:

  • Visual Studio 2015
  • Node.js (tested with v6.5.0)
  • Python 2.7.x
  • node-gyp (tested with 3.0.1)

To buid the NuGet package, open the Visual Studio 2013 Developer Command Prompt and call:

tools\build_double.bat 6.5.0

(you can substitite another version of Node.js).

The script takes several minutes to complete and does the following:

  • builds a few helper tools in C#
  • downloads sources of the selected Node.js version
  • downloads nuget.exe from http://nuget.org
  • builds Node.js shared library for the x86 and x64 flavor
  • builds Edge.js module for the x86 and x64 flavor
  • builds managed EdgeJs.dll library that bootstraps running Node.js in a CLR process and provides the Edge.Func programming model
  • packs everything into a NuGet package

If everything goes well, the resulting NuGet package is located in the tools\build\nuget directory.

Running tests of scripting Node.js in C#

There are functional tests in test\double\double_test and stress tests in test\double\double_stress. Before you can compile these tests, you must register the location of the built NuGet package as a local NuGet feed through the NuGet configuration manager in Visual Studio.

After you have compiled the function tests, the best way to run them is from the command line:

C:\projects\edge\test\double\double_tests\bin\Release> mstest /testcontainer:double_test.dll /noisolation

After you have compiled the stress tests, simply launch the executable, attach resource monitor to the process, and leave it running to observe stability:

C:\projects\edge\test\double\double_stress\bin\Release> double_stress.exe

Use cases and other resources

Accessing MS SQL from Node.js via Edge.js by David Neal
Using ASP.NET and React on the server via Edge.js by Graham Mendick

Contribution and derived work

I do welcome contributions via pull request and derived work.

The edge module is intended to remain a very small component with core functionality that supports interop between .NET and Node.js. Domain specific functionality (e.g. access to SQL, writing to ETW, writing connect middleware in .NET) should be implemented as separate modules with a dependency on edge. When you have a notable derived work, I would love to know about it to include a pointer here.

More

Issues? Feedback? You know what to do. Pull requests welcome.

electron-edge's People

Contributors

alexbeletsky avatar anaisbetts avatar bbaia avatar bmavity avatar dahlbyk avatar dbaeumer avatar dpen2000 avatar dthorpe avatar fredrikl avatar gaelazzo avatar israelg99 avatar jchannon avatar jonmills avatar jskrzypek avatar kexplo avatar kjpou1 avatar lstratman avatar moodmosaic avatar paulprins avatar petermortensen avatar pgermishuys avatar porsager avatar rstuven avatar seedyoon avatar sheepwillprevail avatar smoothdeveloper avatar squallatf avatar srobati avatar tjanczuk avatar tomlm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

electron-edge's Issues

musl libc: error: 'timeval'

Greetings,

On Void-linux musl-x86_64 when trying to npm install electron-edge-js I am getting the following error:

./src/CoreCLREmbedding/json/casablanca/include/cpprest/asyncrt_utils.h:496:47: error: 'timeval' does not name a type; did you mean 'timegm'?
static datetime timeval_to_datetime(const timeval &time);
^~~~~~~
timegm`

the same issue exists on edge too: tjanczuk#612

showing error: "fs.existsSync" is not a function

Hi,
I am running electron-edge for calling method from C# DLL in nodejs. while including electron-edge i am getting this error : "fs.existsSync" is not a function

declare var require: any
var edge = require('electron-edge');
var newapi= edge.func({
assemblyFile: 'C#.dll',
typeName: 'abc.def',
methodName: 'C#api'
});

i am using ionic and electron.

can you please guide me to solve this error. i am totally new to web-technologies.

Thanks,
Kamlesh Khatvani

System.Reflection.AmbiguousMatchException: Ambiguous match found.

Hi,

When i'm trying to use electron-edge (latest) with electron (latest) I get this exception:

[repository]\node_modules\electron-edge\lib\edge.js:168 Uncaught System.Reflection.AmbiguousMatchException: Ambiguous match found.exports.func @ [repository]\node_modules\electron-edge\lib\edge.js:168greet @ index.html:21(anonymous function) @ index.html:17

On this line in the edge.js file:
return edge.initializeClrFunc(options);

When i'm doing this:

      var pathToDll = __dirname + "\\ClassLibrary1.dll";
      var GetCurrentStep = edge.func({
        assemblyFile: pathToDll,
        typeName: 'ClassLibrary1.Player',
        methodName: "GetCurrentStep"
      });

the edgeNative file is:

\node_modules\electron-edge\lib\native\win32\x64\6.5.0\edge_nativeclr

Any idea?

Uncaught Error: Specified procedure could not be found

I am running into the following issue using electron-edge:

Uncaught Error: The specified procedure could not be found.
\\?\C:\dev\Projects\xxx\xxx\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr.node
Error: The specified procedure could not be found.
\\?\C:\dev\Projects\xxx\xxx\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr.node
    at Error (native)
    at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:158:20)
    at Object.Module._extensions..node (module.js:568:18)
    at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:158:20)
    at Module.load (module.js:456:32)
    at tryModuleLoad (module.js:415:12)
    at Function.Module._load (module.js:407:3)
    at Module.require (module.js:466:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\dev\Projects\xxx\xxx\node_modules\electron-edge\lib\edge.js:50:8)

I am referencing it in my electron application using the follow:

var edge = require('electron').remote.require('electron-edge');

I noticed while installing electron-edge via npm I had a similar warning referring to edge_nativeclr.node:

node image

I am running node v6.3.1 and electron v1.3.3

Any clues as to what might be happening?

Problem with IWin32Windows = owned window of BrowserWindow(this)´;

Hello guys,
I am trying to assign to electron's current main window if I open MessageBox.Show(wintarget, ....);

My code is EdgeTest.Startup.cs:

using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EdgeTest
{
public class Startup
{
public async Task Invoke(dynamic input)
{
var payload = (IDictionary<string, object>)input;
var winTarget = (IWin32Window)payload["winTarget"];
return await TargetWin(winTarget);
}

    private async Task<object> TargetWin(IWin32Window ownedWin)
    {
        MessageBox.Show(
            ownedWin,
            "Hello it is an example message!",
            "From NodeJS",
            MessageBoxButtons.OK,
            MessageBoxIcon.Information
            );
        return null;
    }
}

}

And I add function link to open MessageBox while BrowserWindow of electron still opened.
Before I have created MessageBox without owner of current window. It works fine. But I wish MessageBox should "embed" to BrowserWindow of electron with edge.JS

<title>Hello World!</title>

Hello World!

We are using Node.js <script>document.write(process.versions.node)</script>, Chromium <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. link text <script> const {spawn} = require('child_process'); const {app, BrowserWindow} = require('electron'); var edge = require('electron-edge'); function MyFunction(){ var messagebox = edge.func('EdgeTest.dll'); // My dll was compiled by VS 2017 Community let win = new BrowserWindow(this); // I don't know if it is current window of electron application var input = {winTarget : win}; messagebox(input, function (error, result) { if (error) throw error; console.log(result); }); } </script <script> // You can also require other files to run in this process require('./renderer.js') </script>

But it doesn't show messagebox because it doesn't recognize if it gets wrong or wrong owner of window?
How do I fix? Or Is it bugged? If you try without targetwin and Use "IWin32Window owner; and MessageBox.Show(owner, ....);
than "var messagebox = edge.func( "Javascript", .... ) than it works fine but problem with owner of current window. Sorry for bad English.

Could not find edge_nativeclr.node

I'm using electron 1.2.0 with this package and am getting this error when launching the app.

App threw an error during load
Error: The specified module could not be found.
\\?\C:\Users\jeremy_castagnodev\Documents\development\tigerlily\tigerlily-salesman\build\node_modules\electron-edge\lib\
native\win32\x64\6.1.0\edge_nativeclr.node
    at Error (native)
    at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:158:20)
    at Object.Module._extensions..node (module.js:568:18)
    at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:158:20)
    at Module.load (module.js:456:32)
    at tryModuleLoad (module.js:415:12)
    at Function.Module._load (module.js:407:3)
    at Module.require (module.js:466:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\Users\jeremy_castagnodev\Documents\development\tigerlily\tigerlily-salesman\build\node_mod
ules\electron-edge\lib\edge.js:46:8)

OS: Windows 7
Electron Version: 1.2.0
Electron-edge version: 5.0.3-pre1

Failed to find the Edge.js runtime assembly in the dependency manifest list

Hi,
I'm trying to get started with electron-edge. I could run the first hello world example using .net 4.5. But when I try to run the same example using core CLR I get following exception.

App threw an error during load
Error: Failed to find the Edge.js runtime assembly in the dependency manifest list.  Make sure that your project.json file has a reference to the Edge.js NuGet package.
    at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:173:20)
    at Object.Module._extensions..node (module.js:598:18)
    at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:173:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (D:\Personal\TrainingCode\aspnetcore\newClean\node_modules\electron-edge\lib\edge.js:52:10)
    at Object.<anonymous> (D:\Personal\TrainingCode\aspnetcore\newClean\node_modules\electron-edge\lib\edge.js:174:3)

My setup is as follows.
Windows 10 64bit

  1. npm install electron-edge
  2. used dotnet migrate and npm rebuild to build electron-edge and edge-cs
  3. ran sample for .net 4.5
var helloWorld = edge.func(function () {/*
    async (input) => {
        return ".NET Welcomes " + input.ToString();
    }
*/});

  helloWorld('JavaScript', function (error, result) {
      if (error) throw error;
      console.log(result);
  });

It prints the output and worked fine.

Then I switched to core CLR
set EDGE_USE_CORECLR=1

Ran the app and got the exception above. I wasted about a day to get this to work.

Does anyone have a clue?

can not find node_module electron-edge

when I run my program by "npm start",it works well.
But when I packed it as asar and run again,the program can not start,and show error:
image
who can tell me why?

Module did not self register - electron-edge.

I have been trying to build electron-edge for an application. I installed electron-edge using npm and ran the build.bat file inside tools directory of electron-edge and built the module again with node-gyp configure and node-gyp build. Everything was successfully built without any errors. But when I run the app using npm start it throws an error saying "Module did not self register".
Operating system : Windows 10 x64
Node Version : 6.3.1
Electron version : 1.4.4
Please look into this.

Issues installing from NPM

Evening,

I have been trying all day to get electron-edge installed. I keep receiving an error that a module could not be found. I have tried different version of node.js and electron while receiving the same error message. Is there something required im missing? Below is the error i have received.

C:\Users\shuppz\Desktop\electron testing>npm install [email protected] --save

> [email protected] install C:\Users\shuppz\Desktop\electron testing\node_modules\edge-cs
> node tools/install.js


> [email protected] install C:\Users\shuppz\Desktop\electron testing\node_modules\electron-edge
> node tools/install.js

***************************************
Error: The specified module could not be found.
\\?\C:\Users\shuppz\Desktop\electron testing\node_modules\electron-edge\lib\native\win32\x64\6.5.0\edge_nativeclr.node
    at Error (native)
    at Object.Module._extensions..node (module.js:583:18)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\Users\shuppz\Desktop\electron testing\node_modules\electron-edge\lib\edge.js:49:8)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
***************************************
Success: platform check for edge.js: node.js x64 v6.4.0
[email protected] C:\Users\shuppz\Desktop\electron testing
`-- [email protected]
  +-- [email protected]
  `-- [email protected]

npm WARN [email protected] No description

Can't load DLL

I am unable to load the library here:
electron-edge\lib\native\win32\ia32\6.3.0\edge_nativeclr.node

It appears the library has been built with visual studio 2015 and now relies on msvcp140.dll. This file isn't distributed with the build that I have. I am running version 5.9.2-p0.

I worked around the problem by installing the CRT redist from VS 2015. Other people will certainly encounter this.

Fix: msbuild fails during install - unsupported project.json

during install msbuild print 'no project found' warning and quits ...
its during command node tools/install.js - because lib/bootstrap/project.json file is no longer supported ...

after creating lib/bootstrap/project.csproj with content bellow and building it in VS2017 msbuild no longer prinnts 'no project found' ...

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <TargetFramework>netcoreapp1.0</TargetFramework>
   </PropertyGroup>
   <ItemGroup>      
      <PackageReference Include="Edge.js" Version="7.10.1" />
      <PackageReference Include="Edge.js.CSharp" Version="1.2.0" />
   </ItemGroup>
</Project>

The specified module could not be found edge_nativeclr.node

Hi,
I'm getting this error when I try to install electron-edge 5.9.2-p0 on Windows 10. I was having the same error with 5.0.3-pre.

>npm install electron-edge
`-- [email protected]
  +-- [email protected]
  `-- [email protected]

> [email protected] install C:\Work\test\node_modules\electron-edge
> node tools/install.js

log  : Restoring packages for C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.json...
error: Package Edge.js 5.9.2 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Edge.js 5.9.2 supports:
error:   - net40 (.NETFramework,Version=v4.0)
error:   - netstandard1.6 (.NETStandard,Version=v1.6)
error: Package Edge.js.CSharp 1.0.0 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Edge.js.CSharp 1.0.0 supports: netstandard1.6 (.NETStandard,Version=v1.6)
error: One or more packages are incompatible with .NETCoreApp,Version=v1.0.
info : Committing restore...
log  : Writing lock file to disk. Path: C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.lock.json
log  : C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.json
log  : Restore failed in 760ms.

Errors in C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.json
    Package Edge.js 5.9.2 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Edge.js 5.9.2 supports:
      - net40 (.NETFramework,Version=v4.0)
      - netstandard1.6 (.NETStandard,Version=v1.6)
    Package Edge.js.CSharp 1.0.0 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Edge.js.CSharp 1.0.0 supports: netstandard1.6 (.NETStandard,Version=v1.6)
    One or more packages are incompatible with .NETCoreApp,Version=v1.0.

NuGet Config files used:
    C:\Users\pmoleri\AppData\Roaming\NuGet\NuGet.Config
    C:\ProgramData\nuget\Config\Microsoft.VisualStudio.Offline.config

Feeds used:
    https://api.nuget.org/v3/index.json
    C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
Project bootstrap (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
Compiling bootstrap for .NETCoreApp,Version=v1.0
C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.json(13,27): error NU1002: The dependency Edge.js 5.9.2 does not support framework .NETCoreApp,Version=v1.0.
C:\Work\test\node_modules\electron-edge\lib\bootstrap\project.json(14,34): error NU1002: The dependency Edge.js.CSharp 1.0.0 does not support framework .NETCoreApp,Version=v1.0.

Compilation failed.
    0 Warning(s)
    2 Error(s)

Time elapsed 00:00:00.0125696

Load edge native library from: C:\Work\test\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr
***************************************
Error: The specified module could not be found.
\\?\C:\Work\test\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr.node
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\Work\test\node_modules\electron-edge\lib\edge.js:50:8)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
***************************************
Success: platform check for edge.js: node.js x64 v6.3.0

I have Visual Studio 2015 Update 3 and .Net Core installed, although from the README I understand that having .Net 4.5 is enough.

Node: v6.3.0

** Update **

When I try to use it:

C:\Work\test>node
> require("electron-edge")
Load edge native library from: C:\Work\test\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr
Error: The specified module could not be found.
\\?\C:\Work\test\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr.node
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\Work\test\node_modules\electron-edge\lib\edge.js:50:8)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
>
(To exit, press ^C again or type .exit)
>

C:\Work\test>dir C:\Work\test\node_modules\electron-edge\lib\native\win32\x64\6.3.0\edge_nativeclr.node
...
27/07/2016  16:06           157.696 edge_nativeclr.node
               1 File(s)        157.696 bytes

electron.exe.config not working as expected

On a windows machine I have an app.config in C# which belongs to runner.exe (example program) that loads my assembly.dll.
After compilation I get runner.exe.config (derived from the app.config).
I would like electron to call my assembly.dll but i'm not able to add the app.config (calling and running methods in the assembly which don't need a configuration work as expected).
I tried electron.exe.config, I tried node.dll.config (which I assumed was called from the electron.exe).
Another thing is that there are 2 electron.exe processes running, one spawned by the other and i'm not sure if they read the config.
Any help is appreciated.

'npm install electron-edge' fails on CentOS and NetCore SDK 1.0.1

Hi! I'm getting some problems when installing my dependencies when I bring over my application to linux. I'm also getting problems when running the application (module compiled against a different Node.js version using 48, requires 53), but I think this is the root cause.

This is installed on CentOS 7.3, using Node 6.10 from EPEL, and dotnet-dev-centos-x64.1.0.1.tar.gz from microsoft.
Mono is not installed, although it has the same results.

The following was performed when no node_modules folder is present.
dependencies in package.json:
"electron": "^1.4.x",
"electron-debug": "^1.1.0",
"electron-edge": "^6.5.4",
"node-gyp": "^3.5.0",

Sample output:
[devel@CentOS7 electron-linux]$ npm install electron-edge

[email protected] install /home/devel/Desktop/electron-linux/node_modules/edge-cs
node tools/install.js

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

[email protected] install /home/devel/Desktop/electron-linux/node_modules/electron-edge
node tools/install.js

make: Entering directory `/home/devel/Desktop/electron-linux/node_modules/electron-edge/build'
TOUCH Release/obj.target/edge_nativeclr.stamp
CXX(target) Release/obj.target/edge_coreclr/src/common/v8synchronizationcontext.o

*** SNIP - MORE COMPILING ***

CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/pal/pal.unix.o
SOLINK_MODULE(target) Release/obj.target/edge_coreclr.node
COPY Release/edge_coreclr.node
ACTION binding_gyp_build_managed_target_restore_bootstrap_packages lib/bootstrap/project.lock.json
MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
make: *** [lib/bootstrap/project.lock.json] Error 1
make: Leaving directory /home/devel/Desktop/electron-linux/node_modules/electron-edge/build' gyp ERR! build error gyp ERR! stack Error: make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules.bundled/node-gyp/lib/build.js:276:23)
gyp ERR! stack at emitTwo (events.js:106:13)
gyp ERR! stack at ChildProcess.emit (events.js:191:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)
gyp ERR! System Linux 3.10.0-514.16.1.el7.x86_64
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build"
gyp ERR! cwd /home/devel/Desktop/electron-linux/node_modules/electron-edge
gyp ERR! node -v v6.10.1
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok
electron-linux-project /home/devel/Desktop/electron-linux
└─┬ [email protected]
├── [email protected]
└── [email protected]

[devel@CentOS7 electron-linux]$

Ability to execute electron code from within C# app

I am attempting to launch an Electron app from within a C# app. The reason for this is that we have two applications, with a lot of code. The first is the "controlling" application, written in C# and the second is the "rendering" application which is written in Electron.

Is this supported? I can't find any examples, and i'm not seeing references to electron in the code, so i'm guessing it is not supported.

By the way, I suppose I should also mention that I wrote a small test app that attempts to launch the electron sample app (https://github.com/electron/electron-quick-start) via a test C# app, which was unsuccessful.

Here is the test C# idea:

        var func = Edge.Func(@"
          var electron = require('electron');
          return function (data, cb) {
            var init = !!electron.app;
            if (!init) console.log('Could not initialize electron app!');
            cb(null, init);
          };
        ");

        dynamic init = await func(null);
        Console.WriteLine("Initialized Electron: " + init);

The code runs fine. It's just not able to initialize the electron.app.

Unloading of native modules during electron app update

I am facing problems with electron-edge when the electron app which contains electron-edge is updated via electron-builder nsis update mechanism (same problem occured with squirrel update before as well).

electron: =1.4.4
electron-edge: @electron_v1.4.4

What seems to happen, is that the update process terminates the electron-app, deletes old install directory (appname/0.9.0-beta.1), installs to new install directory (appname/0.9.0-beta.2) and starts the app again.
At this point the importing/requiring of electron-edge fails as node-require still looks for electron-edge in the old install directory which is not existing anymore.

could not load edge module: Cannot find module 'C:/Users/username/AppData/Local/Programs/appname/0.9.0-beta.1/resources/app.asar/node_modules/electron-edge/lib/native/win32/x64/6.5.0/edge_nativeclr

Did you experience this problem before and is the assumption that the problem originates from node not being able to unload/clear cache of native modules ( nodejs/node#6160 ) correct? Any way to work around this limitation?

Error: Module version mismatch

Hi, Is not working with insert in electron main.js. pls check. I am using the current versions of this libraries
main.js:

const electron = require('electron')
const edge = require('electron-edge')

shell:

App threw an error during load
Error: Module version mismatch. Expected 49, got 48.
    at Error (native)
    at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:167:20)
    at Object.Module._extensions..node (module.js:568:18)
    at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:167:20)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/fabionunes/Developer/playground/electron-finger/node_modules/electron-edge/lib/edge.js:50:8)

Could not load file or assembly AutoMapper, Version=5.1.1.0, Culture=neutral

Have had a C# library which uses Automapper to map between two objects. When the code is running in C# context only (for e.g. as a console application, windows or web application) the things work fine. Now, the need is to invoke the same C# library from electron-edge. Attempting to do so results in getting the error message below:

Error: Could not load file or assembly 'AutoMapper, Version=5.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER))

How can we address this issue?

using log4net in edge C#

is it possible to use log4net inside the dll's i'm using via edge? if i run my dll via a simple hello world project, the log4net calls log, whereas if i invoke the same methods via edge, the methods run correctly, return correct data, but there is no log4net logging. is there some special namespace issue? i tried including the roslyn //r# for the additional log4net assemble; not luck.

edge_nativeclr.node not declared as a dependency

I am trying to load the file electron-edge with SystemJS and when I'll run the application an error is shown as below:

index.html:28 Error: (SystemJS) 
Module 
C:\Sistemas\RecebimentoDesktop\node_modules\electron-edge\build\Release\edge_nativeclr.node
not declared as a dependency of 
file:///C:/Sistemas/RecebimentoDesktop/node_modules/electron-edge/lib/edge.js

But there is the file edge.js in file:///C:/Sistemas/RecebimentoDesktop/node_modules/electron-edge/lib/edge.js

Thanks.

StackOverflowException during Edge compiling of c# using .Net Core

Trying to use Electron, Edge, and .Net Core.
I'm getting a StackOverflowException when trying to call a method in my own compiled .Net Core assembly.

I followed the suggested additions to the .Net Core project setup etc as described here and here as per Edge documentation.

On Windows 10, using versions:

image

I set up a test project here to illustrate the problem: https://github.com/SeanSnyders/TestExamples/tree/master/Test-Electron-Edge-DotNetCore

To build and run, follow general instructions as per the project readme.md:
npm install
npm run rebuild
npm start

If I change this line
image

to use bridge-inline.js it works fine, but using bridge-external.js and calling the TestMe method in the .NET Core compiled assembly gives me a StackOverflowException during the Edge JIT compiling of the c# code, as illustrated by the trace output when the environment variable COREHOST_TRACE=1 is set:

image

I've tried various things to fix this. Playing around with EDGE_APP_ROOT etc, but no solution just yet.
Is there a problem with the environment, or can Edge not find my assembly? Would be odd giving a StackoverflowException though....

Help appreciated!

call dotnetframework dll Error Occurred Illegal characters in path

I use VS2017 create a .netframework4.5 dll, the dll has use a devExpress control,when electron call this dll ,Error Occurred,, Illegal characters in path
the key codes are as follows
let add = edge.func({ assemblyFile: path.join(__static, 'ClassLibrary1.dll'), typeName: 'ClassLibrary1.Class1', methodName: 'Add' }) ipcMain.on('calltest', (event, arg) => { add(arg, function (error, result) { if (error) throw error console.log(result) }) })
sorry , my english is not good.

Getting a 404: /x64/ path segment is now /win-x64/

OOPS! This is the wrong repository. Chock it up to having too many browser tabs opened.

When I attempt to install this version of node, I get a 404:

D:\VS> nvmw install v5.1.1
Start installing node/v5.1.1 (x64) to C:\Users\ccraig\.nvmw\v5.1.1
Download from https://nodejs.org/dist/v5.1.1/x64/node.exe, and save it as C:\Users\ccraig\.nvmw\v5.1.1\node.exe
404 Not Found
Download C:\Users\ccraig\.nvmw\v5.1.1\node.exe from https://nodejs.org/dist/v5.1.1/x64/node.exe failed

This version exists at
https://nodejs.org/dist/v5.1.1/win-x64/node.exe

rather than at
https://nodejs.org/dist/v5.1.1/x64/node.exe

Memory leak when passing byte[] from .NET to V8

Hi, I'm having some memory leak issues due to byte[] being copied when passing it back. For now I'm directly calling the GC to cleanup but I was wondering if there's any good solution for this (you can clearly see the memory usage going up and then drop when the GC is called upon).

There is (or was) some concern about something related in this issue over at edge's github.

Error in macos

lucifer@LuciferdeMacBook-Pro  ~/Downloads/electron-edge-electron_v1.6.2/samples  node 101_hello_lambda.js
/Users/lucifer/Downloads/electron-edge-electron_v1.6.2/lib/edge.js:33
throw new Error('The edge native module is not available at ' + builtEdge
^

Error: The edge native module is not available at /Users/lucifer/Downloads/electron-edge-electron_v1.6.2/build/Release/edge_coreclr.node. You can use EDGE_NATIVE environment variable to provide alternate location of edge.node. If you need to build edge.node, follow build instructions for your platform at https://github.com/tjanczuk/edge
at Object. (/Users/lucifer/Downloads/electron-edge-electron_v1.6.2/lib/edge.js:33:11)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object. (/Users/lucifer/Downloads/electron-edge-electron_v1.6.2/samples/101_hello_lambda.js:3:12)
at Module._compile (internal/modules/cjs/loader.js:701:30)

make error on Ubuntu 17.10

I'm on ubuntu 17.10 with .NET core 2.13 and Mono 5.8. First time I tried to install electron-edge I got an error due to new version of dot net, so I ran dotnet migrate in electron-edge's directory and then npm rebuild electron-edge in main working directory. The result is this error:

make: Entering directory '/home/matteo/Scrivania/electron-quick-start/node_modules/electron-edge/build'
make: *** No rule to make target '../lib/bootstrap/project.json', needed by 'lib/bootstrap/project.lock.json'.  Stop.
make: Leaving directory '/home/matteo/Scrivania/electron-quick-start/node_modules/electron-edge/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/matteo/.nvm/versions/node/v6.9.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:276:23)
gyp ERR! stack     at emitTwo (events.js:106:13)
gyp ERR! stack     at ChildProcess.emit (events.js:191:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)
gyp ERR! System Linux 4.13.0-32-generic
gyp ERR! command "/home/matteo/.nvm/versions/node/v6.9.0/bin/node" "/home/matteo/.nvm/versions/node/v6.9.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build"
gyp ERR! cwd /home/matteo/Scrivania/electron-quick-start/node_modules/electron-edge
gyp ERR! node -v v6.9.0
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok

How can I fix this?

i can't get it to install

I can't find a reason or solution to this at all, but electron-edge won't install cleanly.

Ubuntu 16.04.2 "Xenial"
Node 6.10.2
Electron 1.6.2
.NET Core 1.0.1

As far as I can tell the .NET Core is installed and working correctly, as is node and electron. The following is the install output.

===========================================================================
bentleys@BENTLEYS:~/Documents/ext_root/tagworkspace/defsapp/electron$ npm install electron-edge

> [email protected] install /home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron/node_modules/edge-cs
> node tools/install.js

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

> [email protected] install /home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron/node_modules/electron-edge
> node tools/install.js

make: Entering directory '/home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron/node_modules/electron-edge/build'
TOUCH Release/obj.target/edge_nativeclr.stamp
CXX(target) Release/obj.target/edge_coreclr/src/common/v8synchronizationcontext.o
CXX(target) Release/obj.target/edge_coreclr/src/common/edge.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/coreclrembedding.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/coreclrfunc.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/coreclrnodejsfunc.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/coreclrfuncinvokecontext.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/coreclrnodejsfuncinvokecontext.o
CXX(target) Release/obj.target/edge_coreclr/src/common/utils.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/pal/pal_utils.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/pal/trace.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/fxr/fx_ver.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/fxr/fx_muxer.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/json/casablanca/src/json/json.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/json/casablanca/src/json/json_parsing.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/json/casablanca/src/json/json_serialization.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/json/casablanca/src/utilities/asyncrt_utils.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/deps/deps_format.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/deps/deps_entry.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/deps/deps_resolver.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/host/args.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/host/coreclr.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/host/libhost.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/host/runtime_config.o
CXX(target) Release/obj.target/edge_coreclr/src/CoreCLREmbedding/pal/pal.unix.o
SOLINK_MODULE(target) Release/obj.target/edge_coreclr.node
COPY Release/edge_coreclr.node
ACTION binding_gyp_build_managed_target_restore_bootstrap_packages lib/bootstrap/project.lock.json
MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
build_managed.target.mk:13: recipe for target 'lib/bootstrap/project.lock.json' failed
make: *** [lib/bootstrap/project.lock.json] Error 1
make: Leaving directory '/home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron/node_modules/electron-edge/build'
gyp ERR! build error
gyp ERR! stack Error: make failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:276:23)
gyp ERR! stack at emitTwo (events.js:106:13)
gyp ERR! stack at ChildProcess.emit (events.js:191:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)
gyp ERR! System Linux 4.4.0-72-generic
gyp ERR! command "/usr/bin/nodejs" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build"
gyp ERR! cwd /home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron/node_modules/electron-edge
gyp ERR! node -v v6.10.2
gyp ERR! node-gyp -v v3.4.0
gyp ERR! not ok
[email protected] /home/bentleys/Documents/ext_root/tagworkspace/defsapp/electron
└─┬ [email protected]
├── [email protected]
└── [email protected]

npm WARN [email protected] No repository field.

===========================================================================

electron-edge vs edge

Hi,

From the README.md I can't tell what electron-edge does compared to edge. Can you explain what electron-edge includes/excludes compared to edge? And perhaps update the README?

Thanks,

Tom

problem with electron 1.3.3 release

Hi, the edge is not working with electron 1.3.3 release. 1.3.2 is ok. pls check.

Error: The specified procedure could not be found.
?\node_modules\electron-edge\lib\native\win32\ia32\6.1.0\edge_nativeclr.node
at Error (native)
at process.module.(anonymous function) as dlopen
at Object.Module._extensions..node (module.js:568:18)
at Object.module.(anonymous function) as .node
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Object. (node_modules\electron-edge\lib\edge.js:46:8)
Thanks

Can't work on Electron 1.7.2!!

edge_nativeclr.node was compiled against a different Node.js version using NODE_MODULE_VERSION 53. This version of Node.js requires NODE_MODULE_VERSION 54.

Can't build a valid win32 application using node 5.12.0

I tried manually building the libraries using tools\build release 5.12.0, but it's trying to use iojs-1.2 libraries instead.

https://gist.github.com/pocesar/bb7f30047d38a3e42698a4afed52d5c9

Although it says successful, when I tried to test the build library it gives:

c:\nodejs\node_modules\electron-edge>test\test ia32 5.12.0

c:\nodejs\node_modules\electron-edge>rem usage: test.bat [ia32|x64 {version}], e.g. test.bat x64 0.10.0
Using node.js: c:\nodejs\node_modules\electron-edge\test\\..\lib\native\win32\ia32\5.12.0\node.exe
Microsoft (R) Visual C# Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.

module.js:440
  return process.dlopen(module, path._makeLong(filename));
                 ^

Error: %1 is not a valid Win32 application.
\\?\c:\nodejs\node_modules\electron-edge\build\Release\edge_nativeclr.node
    at Error (native)
    at Object.Module._extensions..node (module.js:440:18)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (c:\nodejs\node_modules\electron-edge\lib\edge.js:46:8)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (c:\nodejs\node_modules\electron-edge\test\101_edge_func.js:1:74)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:20:19)
    at C:\nodejs\node_modules\mocha\lib\mocha.js:220:27
    at Array.forEach (native)
    at Mocha.loadFiles (C:\nodejs\node_modules\mocha\lib\mocha.js:217:14)
    at Mocha.run (C:\nodejs\node_modules\mocha\lib\mocha.js:469:10)
    at Object.<anonymous> (C:\nodejs\node_modules\mocha\bin\_mocha:404:18)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:148:18)
    at node.js:405:3


  CACHE https://api.nuget.org/v3/index.json
Restoring packages for c:\nodejs\node_modules\electron-edge\test\project.json
Writing lock file c:\nodejs\node_modules\electron-edge\test\project.lock.json
Restore complete, 344ms elapsed

NuGet Config files used:
    F:\ProgramData\NuGet\Config\Microsoft.VisualStudio.Offline.config

I'm using node 5.12.0, windows 10 x64, node-gyp 3.4.0, VS 2015, windows SDK 10.
I can build anything natively using node-gyp (like socket.io, contextify, node-sass), so the tools might not be the culprit.

Unable to access the CLR method to wrap through reflection

i want use electron edge but i received this error
Uncaught System.InvalidOperationException: Unable to access the CLR method to wrap through reflection. Make sure it is a public instance method.
my .net code:

namespace electron_factorial
{
    public class MyMath
    {
        public int Factorial(int number)
        {
            if (number < 2)
                return number;
            return Factorial(number - 1)*number;
        }

        public Task<object> CalcFactorial(object obj)
        {
            return Task.Factory.StartNew(() => Factorial((int) obj) as object);
        }
    }
}

my js code:

    <script>
  function  myFunction()
    {
      var {remote}=require("electron");
      var edge = require('electron-edge');
      var CalcFactorial = edge.func({
           assemblyFile: 'electron-factorial.dll',
           typeName: 'electron_factorial.MyMath',
           methodName: "ClacFactorial"
      });

      document.getElementById("calc").addEventListener("click", function (e) {
           var inputText = document.getElementById("txtnumber").value;
           CalcFactorial(inputText, function (error, result) {
                document.getElementById("factorial").innerHTML = result;
           });
      });
    }

    </script>

No such module: atom_common_app when trying to call C# dll method from angular in renderer process

I am trying to call a C# dll in the renderer process using electron-edge. The following code works when i call it directly from the renderer.js file, but when i pass the "integration" variable to angular, and angular calls it later on, i get the error at the bottom.
I dont know how the behaviour of calling it from the renderer process or from angular might cause a difference.

Does anyone has some ideas?

 var elec = require('electron');
 var edge = elec.remote.require('electron-edge')
 var csharpInvoke = edge.func({
    assemblyFile: '../Shared/bin/Debug/Shared.dll',
});

var csharpProxy = csharpInvoke(null, true);
var integration = csharpProxy.createIntegration(null, true);
console.log(integration);
console.log(integration.getChildren('ROOT', true)); // Works! but when called from angular, doesnt!

Full stackstrace

Error: No such module: atom_common_app
at Error (native)
at process.atomBinding (C:_Data\Repositories\sleek-application\Client\node_modules\electron\dist\resources\electron.asar\common\init.js:8:22)
at Object. (C:_Data\Repositories\sleek-application\Client\node_modules\electron\dist\resources\electron.asar\browser\api\app.js:3:26)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.require (module.js:483:17)
at require (internal/module.js:20:19)


(anonymous function) @ angular.js:11595
(anonymous function) @ angular.js:8545
invokeLinkFn @ angular.js:8216
nodeLinkFn @ angular.js:7723
compositeLinkFn @ angular.js:7076
publicLinkFn @ angular.js:6955
updateView @ angular-ui-router.js:3839
(anonymous function) @ angular-ui-router.js:3801
$broadcast @ angular.js:14704
$state.transition.resolved.then.$state.transition @ angular-ui-router.js:3218
processQueue @ angular.js:13172
(anonymous function) @ angular.js:13188
$eval @ angular.js:14385$digest @ angular.js:14201
$apply @ angular.js:14490done @ angular.js:9647
completeRequest @ angular.js:9837
requestLoaded @ angular.js:9778

Electron-Edge fails to install with a MSBuild error

When trying to install electron-edge through npm, the application does not install correctly, rendering the package useless:

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
***************************************
Error: The edge module has not been pre-compiled for node.js version v8.2.1. You must build a custom version of edge.node. Please refer to https://github.com/tjanczuk/edge for building instructions.
    at determineVersion (C:\Root\App\app-contents\node_modules\electron-edge\lib\edge.js:18:11)
    at Object.<anonymous> (C:\Root\App\app-contents\node_modules\electron-edge\lib\edge.js:30:102)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (C:\Root\App\app-contents\node_modules\electron-edge\tools\checkplatform.js:2:2)
***************************************
Success: platform check for edge.js: node.js x64 v8.2.1
npm WARN Invalid name: "Aplicación Prototipo"
npm WARN app-contents No description
npm WARN app-contents No repository field.
npm WARN app-contents No README data
npm WARN app-contents No license field.

+ [email protected]
added 3 packages in 9.01s

Node.JS version: 8.2.1
NPM version: 5.3.0
Electron version: 1.6.11

Edge with .net core external dll sample required.

I found this thread useful in this regard. tjanczuk#463. But I could not get this to work after building .net core project and generating .deps file. The electron app crashes as soon as I set EDGE_APP_ROOT to deps file location.
Everything working fine when dotnetcore code running inline with javascript. But I can't get external dotnetcore dll referenced. I couldn't find any step by step documentation or sample app in this regard, except for the thread above.

Here are the steps I followed,

  1. Create electron quick start app.
  2. Set the global.json to point to preview version of dotnetcore as newer version gave me build errors with electron-edge.
{
  "sdk": {
    "version": "1.0.0-preview2-003121"
  }
}
  1. Install electron-edge npm install electron-edge
  2. Ran helloworld sample. Working fine with dot net framework.
  3. set EDGE_USE_CORECLR=1
  4. Ran helloworld sample. Working fine with core clr.
  5. Create new dotnet core class library project with same sdk version 1.0.0-preview2-003121
  6. Added Edge.js nuget
{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable"
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
        "type": "platform",
        "version": "1.0.0"
        },
        "Edge.js": "6.5.0"
      }
    }
  }
}
  1. With dotnet restore and dotnet build created deps file and the dll
  2. When I point the EDGE_APP_ROOT to the debug folder where deps file and dll lives and run my electron app it crashes. Event log has following error.
Faulting application name: electron.exe, version: 1.6.8.0, time stamp: 0x5907b4b0
Faulting module name: KERNELBASE.dll, version: 10.0.15063.296, time stamp: 0xa0527b0c
Exception code: 0xc0000005
Fault offset: 0x0000000000030b24
Faulting process id: 0x20e0
Faulting application start time: 0x01d2d515deabec6f
Faulting application path: D:\Personal\TrainingCode\elec-edge\electron-q\node_modules\electron\dist\electron.exe
Faulting module path: C:\WINDOWS\System32\KERNELBASE.dll
Report Id: 53e8c650-6ca6-4bfa-afca-afb9300dbc24
Faulting package full name: 
Faulting package-relative application ID: 
  1. The crash happen when I require electron-edge. So it is not something with the javascript code I was using to refer to the dll. Please note I'm also confused how to refer to core dll in the javascript code as well. e.g You map a method in a core dll to a javascript function. Should it be static method or method with special signature like you do in inline c# code?

Please let me know if there is anything wrong with my steps referring my own core dll with edge. If you have a complete working sample it is much appreciated.

Error: Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER))

I admit that this issue may sound a duplicate of issue tjanczuk#496, but I cannot overcome the problem. I guess either a point is missing in the documentation of edge / electron-edge or something is not clear to me.

I create a super simple C# library in .Net Core 1.1 with .Net Standard 1.6. I finished dotnet restore, dotnet build and dotnet release etc. .... per the documentation successfully. Things went on well and I moved all DLLs, json files, etc. from the publish folder to a folder called "dll" within the folder where node runs. So, it looks like this: C:\electron-quick-start\dll

var clrMethod = edge.func({
    assemblyFile: 'dll\\MyLibrary.dll',
    typeName: 'MyLibrary.Startup',
    methodName: 'Invoke'
});

clrMethod('This text comes from JavaScript!', function (error, result) {
    if (error) throw error;
    console.log(result);
});

When I run the js file, I receive the error message mentioned in the subject line. Then I set the following environment variables:

EDGE_USE_CORECLR=1
EDGE_APP_ROOT = C:\electron-quick-start\dll

But I received this error message / exception:

TypeError: edge.initializeClrFunc is not a function

Even I tried to put all contents of "dll" folder side by side where node is running and that resulted into no success. Also, I set app root to the exact publish folder generated by dotnet release and that was not conclusive either.

What is missing in this exercise or may have been done wrong?!

As a side note: I am using the recent version of electron-edge.

Support for .NET Core 2.0

Is .NET Core 2.0 supported under Linux? I tried a hello world example, but it gave me a CoreCLR initialization error.

index.js looks like this:

var edge = require('electron-edge');

var helloWorld = edge.func(`
    async (input) => { 
        return ".NET Welcomes " + input.ToString(); 
    }
`);

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

Trying to run it produces the following output:

$ node_modules/.bin/electron index.js 
CoreClrEmbedding::Initialize - Failed to initialize CoreCLR, HRESULT: 0x80070057
App threw an error during load
TypeError: edge.initializeClrFunc is not a function
    at Object.exports.func (/home/theowl/projects/work/dotnet/testapp/node_modules/electron-edge/lib/edge.js:169:17)
    at Object.<anonymous> (/home/theowl/projects/work/dotnet/testapp/index.js:3:23)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at loadApplicationPackage (/home/theowl/projects/work/dotnet/testapp/node_modules/electron/dist/resources/default_app.asar/main.js:280:12)
    at Object.<anonymous> (/home/theowl/projects/work/dotnet/testapp/node_modules/electron/dist/resources/default_app.asar/main.js:322:5)
    at Module._compile (module.js:571:32)
/home/theowl/projects/work/dotnet/testapp/node_modules/electron/dist/resources/default_app.asar/main.js:6068: Uncaught TypeError: edge.initializeClrFunc is not a function

Electron: v1.5.0
Node.js: v7.4.0
.NET Core: v2.0.0
OS: Fedora 26

Trying to get Electron Edge up and running in Raspberry Pi Pixel for VBox i386 build.

I'm trying to build a Electron application for Windows and the Raspberry Pi Linux distribution. I really want to use Electron-Edge to allow me to use C# libraries. I'm looking to do a proof of concept for Windows, Raspberry Pi VBox, and the Actual Raspberry Pi ARM in the future.

The only issue I see is that Electron-Edge requires Mono x64, why? I have met all the other requirements. Is there something I need or can do in the build to fix this? Also what would I need to do for Mono Arm in the future?

I have install Mono 4.2.4 i386 and have built everything, but I'm getting the following error:

Uncaught Error: /home/pi/GH/node_modules/electron-edge/build/Release/edge_nativeclr.node: undefined symbol: _ZN2v816FunctionTemplate3NewEPNS_7IsolateEPFvRKNS_20FunctionCallbackInfoINS_5ValueEEEENS_5LocalIS4_EENSA_INS_9SignatureEEEi
at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:173:20)
at Object.Module._extensions..node (module.js:598:18)
at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:173:20)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object. (/home/pi/GH/node_modules/electron-edge/lib/edge.js:51:10)
at Object. (/home/pi/GH/node_modules/electron-edge/lib/edge.js:172:3)

What needs to be changed in the build to allow this to work?

.NET dll in electron app

I hope this is not a silly question.

I have a .NET dll that I would like to use in my electron app.
In particular, I need to call a method of the dll and receive event raised from the dll.

Is this possible with electron-edge?
Many thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.