是否有ECMAScript的.NET CLR / DLR实现?

时间:2009-07-02 06:01:34

标签: .net javascript clr dynamic-language-runtime ecma262

有没有人知道针对 .NET CLR / DLR 的ECMAScript的真实(i ..无蒸发器)实现?理想情况下,像 Rhino是针对Java的。在.NET Framework / Mono Framework上运行的可靠Rhino端口将是完美的。

我只看过一些提到的项目,但从来没有看到任何曝光或实际上我曾经能够运行脚本的东西。这就是我所知道的:

  • MSScriptControl ActiveX Control :AFAIK,这是Microsoft最后一个真正符合ECMAScript标准的实现(运行JScr​​ipt 5.7)。我已经与MSScriptControl集成,但不认为COM互操作是这个问题的答案。 x64是此选项的杀手锏。

  • JScript.NET :我不算JScript.NET,因为它永远无法成功解析我的任何真实脚本。闭包似乎有问题。

  • Managed JScript :听起来像我想要的但似乎已经死在了水中。这是DLR的一个主要示例实现,但随后与SilverLight纠缠在一起,并且自2007年以来似乎已经逐渐消失。关于这种状态的可信来源将是有帮助的。

  • MyJScript :构建为DLR的教程实施。有人知道这是一个完整的实现吗?

  • Jint :.NET的JavaScript解释器。 尚不支持Currying或try - catch - finally

  • RemObjects Script for .NET :一个有趣的竞争者仍在开发中。我对他们的营销很困惑,实际上会是什么,但听起来最终可能是合适的。如果有人知道更多相关内容也会有所帮助。

  • V8 for .NET :如果有人将V8移植到.NET,这将会很棒。据我所知,这方面也没有太大的努力。该链接是一个从托管C ++包装器调用它的想法。

对于后台,我希望能够在.NET中执行JavaScript;即将一组脚本加载到上下文中并调用该上下文并检索执行结果。目前,我通过繁琐的COM Interop跳过箍使用MSScriptControl。 COM的不一致使得部署和确保一致的执行非常困难。

我希望能够在.NET中执行相当复杂的JavaScript测试工具。这不是用于创建用户宏或简单的小脚本;我需要像Rhino这样的真实JavaScript环境。如果实现是在CLR(而不是COM)之上运行的,那么这对当前的一些问题确实有帮助。

9 个答案:

答案 0 :(得分:17)

目前,我已在我的EcmaScript.NET端口(项目)中修改了YUICompressor.NET的版本。

如果您抓住source code from here,我已将修改后的代码包含在项目中,您可以参考该代码。这是我在.NET中找到的唯一代码来源,它可以处理解析javascript,服务器端。

不幸的是,我不记得我是如何找到它的。我必须承认,这是一个艰难的过程。我想我找到了一些关于Rhino(java代码)的Mozilla dev页面的引用,这让我发现了C#.NET的实现。

我不得不稍微修改它以与YUI Compressor人员对其代码分支所做的一些更改同步。所以我修改过的分支可能不是最好的..但它是我见过最接近原始Java分支的。

自2007年以来,尚未触及EcmaScript.NET的原始c#代码...至少对于下载页面而言。

也许这可能会有所帮助??

HTH。

答案 1 :(得分:13)

仍然大致活着:

  • Jurassic(去年有过承诺。)
  • Jint(目前正在接受请求。)

其他项目,主要是死亡:

疯狂方法:

  • Rhino over IKVM(在评论中提及,但这里有关于这样做的更多信息的链接。)

答案 2 :(得分:12)

没人提到侏罗纪http://jurassic.codeplex.com/ 我不知道它有多好(性能,可用性等),但至少它解析相当复杂的脚本(其他实现没有),它支持ECMAScript 5规范。我只是在这里添加链接以供参考。

答案 3 :(得分:8)

没人提到ClearScript,所以ClearScript

这不是一个实现;它是一个支持V8,JScript和VBScript的互操作包装器,有一个非常好的API可以从.NET代码中调用它们。

CodePlex页面的示例代码:

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

// create a script engine
using (var engine = new V8ScriptEngine())
{
    // expose a host type
    engine.AddHostType("Console", typeof(Console));
    engine.Execute("Console.WriteLine('{0} is an interesting number.', Math.PI)");

    // expose a host object
    engine.AddHostObject("random", new Random());
    engine.Execute("Console.WriteLine(random.NextDouble())");

    // expose entire assemblies
    engine.AddHostObject("lib", new HostTypeCollection("mscorlib", "System.Core"));
    engine.Execute("Console.WriteLine(lib.System.DateTime.Now)");

    // create a host object from script
    engine.Execute(@"
        birthday = new lib.System.DateTime(2007, 5, 22);
        Console.WriteLine(birthday.ToLongDateString());
    ");

    // use a generic class from script
    engine.Execute(@"
        Dictionary = lib.System.Collections.Generic.Dictionary;
        dict = new Dictionary(lib.System.String, lib.System.Int32);
        dict.Add('foo', 123);
    ");

    // call a host method with an output parameter
    engine.AddHostObject("host", new HostFunctions());
    engine.Execute(@"
        intVar = host.newVar(lib.System.Int32);
        found = dict.TryGetValue('foo', intVar.out);
        Console.WriteLine('{0} {1}', found, intVar);
    ");

    // create and populate a host array
    engine.Execute(@"
        numbers = host.newArr(lib.System.Int32, 20);
        for (var i = 0; i < numbers.Length; i++) { numbers[i] = i; }
        Console.WriteLine(lib.System.String.Join(', ', numbers));
    ");

    // create a script delegate
    engine.Execute(@"
        Filter = lib.System.Func(lib.System.Int32, lib.System.Boolean);
        oddFilter = new Filter(function(value) {
            return (value & 1) ? true : false;
        });
    ");

    // use LINQ from script
    engine.Execute(@"
        oddNumbers = numbers.Where(oddFilter);
        Console.WriteLine(lib.System.String.Join(', ', oddNumbers));
    ");

    // call a script function
    engine.Execute("function print(x) { Console.WriteLine(x); }");
    engine.Script.print(DateTime.Now.DayOfWeek);

    // examine a script object
    engine.Execute("person = { name: 'Fred', age: 5 }");
    Console.WriteLine(engine.Script.person.name);
}

答案 4 :(得分:7)

您可以查看Jint(http://jint.codeplex.com),它是一个开源的ECMAScript解释器。

<强>更新

Github在https://github.com/sebastienros/jint

上提供了新的重写版本

答案 5 :(得分:6)

您应该在Codeplex上尝试Javascript .NET(http://javascriptdotnet.codeplex.com/)。他们使用托管C ++包装v8,然后你可以将这个库与.NET应用程序一起使用,它就像魅力一样。如果你问我,开源提供了一些非常好的功能。

干杯。

答案 6 :(得分:4)

你可以使用Jscript.net,它实际上可以使用任意的javascript代码;您只需要通过使用jsc /fast- bar.js

进行编译来关闭“快速模式”

我没有测试过这个;我只是在阅读this post时注意到它,并认为这将是另一个合理的解决方案。 MSDN有the docs for this optionwhat the limitations are if you don't use it

答案 7 :(得分:4)

V8.NET

这个可能是我遇到过的最好的一个。
https://v8dotnet.codeplex.com/documentation

此外,它的设计始于Mono端口。 它使您可以从托管代码完全控制V8引擎的功能。

答案 8 :(得分:1)

我更喜欢JINT而不是 其他。

JINT可能很慢,但它很容易调试并与您自己的.NET类进行交互。 (每次为jscript.dll等设置[ComVisile]属性都很困难。

在线程方面,JINT和Jurassic正如我所期望的那样工作。为了使用JScript引擎或Google V8,您必须注意UI线程问题。

但是,JINT在某些方面已过时,因为我无法编译JQuery 1.5或更高版本。

我希望侏罗纪能够通过创建'AllowBob'sCLRClass=true'来消除其限制,以便坚持自己的课程。

我必须重写整个班级。这很难......