C# 使用 Microsoft.JScript 动态编译执行 JavaScript

南乔
南乔
发布时间:2026-10-14| 5人浏览过
原创

介绍如何在 C# 应用程序中利用 CodeDOM 技术动态编译并执行 JavaScript 代码片段。该方案无需外部引擎,仅依赖 .NET Framework 内置库即可实现脚本的动态加载、编译与反射调用。

原理与目标

C# 提供了 CodeDOM (Code Document Object Model) 框架,允许以编程方式生成和编译代码。虽然主要支持 C# 和 VB.NET,但 .NET Framework 内部包含了微软官方的 JavaScript 编译器提供程序 (Microsoft.JScript.JScriptCodeProvider)。利用这一特性,可以在运行时接收用户输入的 JavaScript 字符串,将其编译为动态程序集,并通过反射机制执行其中的特定函数,从而在后端环境灵活地处理前端传来的脚本逻辑。

准备条件

  • 运行环境:.NET Framework(建议 4.x 及以上版本)。注意:Microsoft.JScript 是较老的组件,在 .NET Core / .NET 5+ 的跨平台运行时中已移除,需迁移至 IronJS 或 DynamicExpresso 等第三方库。
  • 关键命名空间:
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;

第1步:创建编译提供者实例

目的是获取用于解析和编译 JavaScript 语法的核心引擎。

  • 动作:实例化 JScriptCodeProvider 并将其存储为静态只读字段,避免重复创建开销。
private static readonly CodeDomProvider _provider = new Microsoft.JScript.JScriptCodeProvider();

第2步:定义 JavaScript 源字符串

目的是构造合法的 JScript 代码块。JScript 采用类似 AS3/Java 的包结构,必须包含 package 声明才能被正确识别。

  • 入口:字符串变量 scriptStr。
  • 重要参数:脚本必须包含 package <Name> { ... } 结构,且通常建议使用 static function 以便直接调用。
private const string scriptStr = @"package fhs 
{ 
    public class MyJs 
    { 
        public static function test1(paramr1) 
        { 
            var retString = paramr1 + '是无敌的!'; 
            return retString; 
        } 
    } 
}";

第3步:配置编译参数

目的是设置编译器行为,确保生成的代码在内存中运行,不产生临时文件。

  • 动作:创建 CompilerParameters 对象。
  • 重要参数:GenerateInMemory = true,表示编译后的 DLL 直接加载到当前 AppDomain 内存中;GenerateExecutable = false(默认)。
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;

第4步:执行编译并获取结果

目的是将 JS 源码转换为 .NET 可执行程序集 (Assembly)。

  • 动作:调用 _provider.CompileAssemblyFromSource。
  • 完成状态判断:检查 CompilerResults.Errors.HasErrors。若存在错误,应抛出异常或记录日志;若成功,则通过 results.CompiledAssembly 获取程序集引用。
CompilerResults results = _provider.CompileAssemblyFromSource(parameters, scriptStr);
if (results.Errors.HasErrors)
{
    // 处理编译错误逻辑
    throw new Exception("JScript 编译失败: " + results.Errors[0].ErrorText);
}
Assembly assembly = results.CompiledAssembly;

第5步:反射调用指定方法

目的是在已加载的程序集中找到对应类和方法并执行。

  • 步骤 A:获取类型。使用完全限定名称(包名.类名)获取 Type。
  • 步骤 B:调用成员。使用 BindingFlags.InvokeMethod 进行静态方法调用。
// 假设 JS 代码中 package 为 fhs, 类为 MyJs
Type evaluateType = assembly.GetType("fhs.MyJs");

// 调用名为 jsMethodName 的静态方法,传入数组作为参数
object retObj = evaluateType.InvokeMember(
    jsMethodName, 
    BindingFlags.InvokeMethod,
    null,          // Binder (使用默认绑定器)
    null,          // Target (静态方法传 null)
    testParams     // 参数数组
);

第6步:封装实用方法

为了方便复用,可以将上述逻辑封装为一个通用的静态方法 JScriptRun。

public static object JScriptRun(string jsMethodName, object[] testParams)
{
    // 1. 准备参数
    CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateInMemory = true;

    // 2. 编译脚本 (此处简化,实际应用中 scriptStr 可能随参数变化或预先定义)
    CompilerResults results = _provider.CompileAssemblyFromSource(parameters, scriptStr);
    
    if (results.Errors.HasErrors)
    {
        throw new InvalidOperationException($"JS 编译出错: {results.Errors[0].ErrorText}");
    }

    // 3. 获取类型并执行
    Assembly assembly = results.CompiledAssembly;
    Type _evaluateType = assembly.GetType("fhs.MyJs");
    
    object retObj = _evaluateType.InvokeMember(jsMethodName, BindingFlags.InvokeMethod,
        null, null, testParams);
    
    return retObj;
}

完成判断

当 JScriptRun 返回预期的返回值对象(如字符串、数字或自定义对象),且未抛出任何编译或运行时异常时,表示 JS 脚本已成功在 C# 环境中动态执行。可以通过 Console.WriteLine 或断点查看返回值来验证。

简要总结

以上介绍了在 .NET Framework 环境下,通过 JScriptCodeProvider 实现 C# 执行 JavaScript 动态编译的完整流程。该方法利用 CodeDOM 框架实现了脚本语言的轻量级集成,适合处理简单的逻辑运算或规则转换场景。需要注意的是,该方案依赖于老旧的微软 JScript 引擎,在现代 .NET Core/5+ 环境中不再可用,生产环境建议考虑使用更活跃的开源脚本执行库。以上就是关于C#执行js动态编译方法的详细内容,更多关于C#脚本引擎技术的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。