我见过几个应用程序,它们允许用户通过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.CSharp
和System.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
希望它能有所帮助!