将JavaScript和VBScript添加到您的.NET Apps

目录

介绍

概念化这个混乱

使用这个混乱


GitHub下载最新版本

介绍

我希望在构建解析器之类时稍事休息,并做一些不同的事情,因此,我整理了一个方便的小库,用于为.NET应用程序添加脚本支持。

有时候,我发现需要在我的应用程序中执行JavaScript,有时需要抓取,有时只是为了获得JS脚本支持(VBScript也可以使用),并且至少有一次需要进行遗留ASP仿真。

Microsoft提供了COM接口来使用这些接口,但是从.NET使用它们却很丑陋。

幸运的是,这个小库使它变得容易。

概念化这个混乱

Microsoft提供了可扩展的脚本框架,它们在旧版ASP页面和Internet Explorer中使用。默认情况下Windows附带的VBScriptJavaScriptJScript中),但第三方也加入了其他的内容。

这些脚本引擎是COM可见的,并将其脚本公开为COM对象,这些对象可以调用您的代码或从您的代码中调用。唯一的麻烦是接口混乱。

我所做的是将这些接口包装成两个易于使用的对象,ScriptHostScriptEngine

使用这个混乱

首先,脚本引擎不能自主存在。他们需要一个扎根的地方。这就是ScriptHost的作用。ScriptHost管理脚本引擎的创建和生命周期,以及为脚本引擎提供各种服务,例如错误报告和对象检索。在创建任何脚本引擎之前,我们必须创建这些小家伙之一。完成后请记住将其丢弃。关闭脚本主机也会同时关闭由它创建的所有引擎。

接下来,我们有了ScriptEngine,您可以通过ScriptHost.Create()获得它。这些代表脚本代码的自治区域。要了解这意味着什么,请知道网页中的每个<script>块都将与其中之一相对应,并且页面本身就是ScriptHost。传递语言以Create()获取所需语言的脚本引擎。有一个快速” JS引擎,您可以通过传递ChakraJS常量来访问它,但我尚未对其进行测试,而且我不确定它的实际速度。

使用ScriptEngine,我们可以Evaluate()表达式,Run()语句或AddCode()脚本块。我们还可以将对象添加到Globals字典中,然后可以通过脚本代码中的名称对其进行访问。

希望演示代码可以使所有内容变得清晰:

Console.WriteLine("Creating script host");
using (var host = new ScriptHost())
{
    // create a JavaScript engine
    Console.WriteLine("Creating javascript engine");
    var engine = host.Create("javascript"); // you can use the ChakraJS const here 
                                            // for IE9+'s fast engine
                                            // evaluate an expression
    Console.WriteLine("Evaluate 2+2: ");
    Console.WriteLine(engine.Evaluate("2+2"));
                
    // add some code to the current script
    Console.WriteLine("Add code: var i = 1;");
    engine.AddCode("var i = 1;");
                
    // get the object for the script
    Console.Write("i = ");
    dynamic obj = engine.Script;
                
    // print var i
    Console.WriteLine(obj.i);
                
    // add an app object to the script
    Console.WriteLine("Add global app object");
    engine.Globals.Add("app", new AppObject());
                
    // let the script call the app object
    Console.Write("Run \"app.writeLine('Hello World!');\": ");
    engine.Run("app.writeLine('Hello World!');");
}

请注意,我们已经在上面的脚本引擎中添加了AppObject。这是它的定义:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch /*.AutoDual */)]  // automatically 
                                 // implements com interface IDispatch ( and IUnknown )
public class AppObject
{
    /// <summary>
    /// allows scripts to write to the console
    /// </summary>
    public void writeLine(string s) { Console.WriteLine(s); }
}

请注意,我们从System.Runtime.InteropServices中添加了几个属性。这是必需的,以便.NET创建使脚本通过COM/OLE Automation与对象进行通信所需的基础结构。如果不添加这些内容,则脚本将无法与对象通信,并且会出现错误。

还要注意,奇怪的是,尽管每个脚本引擎都有自己的全局变量集合,但是脚本站点内的所有全局变量共享同一个命名容器。这意味着无论使用哪个脚本引擎创建,每个名称仅支持一个全局名称。如果两个脚本引擎的项目名称相同,则只有第一个实例与该名称关联。可以将一个对象添加到具有相同名称的两个或多个脚本引擎中。我不是这样设计的——这是Microsoft Active Script框架设计的一部分。

这些涵盖了它。从这里开始并向您的应用程序添加JavaScriptVBScript脚本应该足够简单。

发布了69 篇原创文章 · 获赞 133 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/104116201