将用户脚本引擎添加到我的应用程序中



我见过几个应用程序,它们允许用户通过vb脚本或javascript添加自定义项。这方面的一个重要例子是通过vbscript的office插件或带有ruby脚本的RPG制造商。

我想在我的一个应用程序中添加一个选项,让用户用某种脚本语言编写一些自定义规则,每次尝试保存/提交网页时都会运行

我知道这个问题有点深,但在谷歌上花了大约一个小时后,我甚至不知道从哪里开始解决这类问题。我知道尝试这样做有很多需要考虑的地方。

请给我指正确的方向。

根据您想要支持的语言,有几个选项。VB脚本可以使用MSScriptControl完成,C#可以使用Microsoft.CSharp.完成

下面是我刚刚从数据库中提取C#脚本并执行它的一个快速示例。请注意,这只接受字符串,因此如果您希望参数是一个集合或不同的数据类型,则必须对其进行调整。

value = CreateTransformMethodInfo(_script.ScriptBody).Invoke(null, args.Select(x => x.Value).ToArray()); //args would be the arguments in your script
public static MethodInfo CreateTransformMethodInfo(string script)
    {
        using (var compiler = new CSharpCodeProvider())
        {
            var parms = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory = true,
                CompilerOptions = "/optimize",
                ReferencedAssemblies = { "System.Core.dll" }
            };
            return compiler.CompileAssemblyFromSource(parms, script)
                .CompiledAssembly.GetType("Transform")
                .GetMethod("Execute");
        }
    }

然后实际的脚本看起来是这样的:

public class Transform
{
    public static string Execute(string firstName)
    {
        return "Test";
    }
}

需要注意的一点是,您需要将类命名为"Transform",并将每次运行的方法命名为"Execute",因为您可以看到我们在编译要运行的方法时使用了这两个值。不过,只要"正在执行"的类和方法保持Transform/Execute,就可以随心所欲地命名助手类或方法。

如果您希望编码在客户端,您可以使用Javascript,并且只需使用eval(userCode),其中用户代码是一个字符串

如果您愿意使用c#在服务器端运行用户的代码,那么可以使用带有库Microsoft.CSharpSystem.CodeDom.Compiler的内置编译器。可以这样做:

string code = @"
    using System;
    namespace First
    {
        public class Program
        {
            public static void Main()
            {
            " +
                "Console.WriteLine("Hello, world!");"
                + @"
            }
        }
    }
"; //Assume this is the code the client gave you
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true; //You can add references to libraries using parameters.ReferencedAssemblies.Add(string - name of the assembly).
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); //Compiling the string to an assembly
if (results.Errors.HasErrors)
{
    StringBuilder sb = new StringBuilder();
    foreach (CompilerError error in results.Errors)
    {
        sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
    }
    throw new InvalidOperationException(sb.ToString());
} //Error checking
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("First.Program"); //Getting the class object
MethodInfo main = program.GetMethod("Main"); //Getting the main method to invoke
main.Invoke(null, null); //Invoking the method. first null - because the method is static so there is no specific instance to run in, second null tells us there are no parameters.

代码段取自代码项目:http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime

希望它能有所帮助!

相关内容

最新更新