c#和动态字符串脚本
我想知道我应该如何实施我正在进行的项目的关键部分。本质上是数据映射,在这里我复制字段x并将其放入字段y。但是,在转换过程中,需要具备一些动态更改(使用字符串操纵)该值的能力 我想要的是一个文本框,用户可以在其中输入脚本,允许他们使用脚本语言(最好是VBScript)修改该值。这将允许他们进行简单的操作,例如本例,将使用一个子字符串:c#和动态字符串脚本,c#,scripting,dynamic,C#,Scripting,Dynamic,我想知道我应该如何实施我正在进行的项目的关键部分。本质上是数据映射,在这里我复制字段x并将其放入字段y。但是,在转换过程中,需要具备一些动态更改(使用字符串操纵)该值的能力 我想要的是一个文本框,用户可以在其中输入脚本,允许他们使用脚本语言(最好是VBScript)修改该值。这将允许他们进行简单的操作,例如本例,将使用一个子字符串: Mid({input_value}, 2, 4) 在哪里 将在运行时替换为实际值 因此,例如,如果“字段x”的输入是“这是一个测试”,并且他们使用上面的示例sta
Mid({input_value}, 2, 4)
在哪里
将在运行时替换为实际值
因此,例如,如果“字段x”的输入是“这是一个测试”,并且他们使用上面的示例start=2和length=4,那么保存到“字段y”中的值将是“his”
我知道如何以scipt的身份从C#运行VBScript,这不是问题。但是,是否可以在运行时运行和评估上述srcipt,并将输出记录回C#变量
否则,有人对我如何处理这个问题有什么建议吗
非常感谢您可能想看看基于IronPython或IronRuby的语言。两者都允许嵌入,Michael Foord对如何将它们嵌入到应用程序中有自己的见解 如果您使用标准的DLR接口,我相信您可以嵌入任何语言,包括和。本·霍尔在《红门》的制作申请中有一篇文章 我认为您需要查看下面显示的SetVariable()和GetVariable()方法,以获取设置和从脚本返回数据的示例:
public string evaluate(string x, string code)
{
scope.SetVariable("x", x);
scope.SetVariable("button", this.button);
try
{
ScriptSource source = engine.CreateScriptSourceFromString(code,
SourceCodeKind.Statements);
source.Execute(scope);
}
catch (Exception ex)
{
return "Error executing code: " + ex.ToString();
}
if (!scope.VariableExists("x"))
{
return "x was deleted";
}
string result = scope.GetVariable<object>("x").ToString();
return result;
}
公共字符串求值(字符串x,字符串代码)
{
scope.SetVariable(“x”,x);
scope.SetVariable(“button”,this.button);
尝试
{
ScriptSource=engine.CreateScriptSourceFromString(代码,
SourceCodeKind.声明);
来源、执行(范围);
}
捕获(例外情况除外)
{
返回“执行代码时出错:”+ex.ToString();
}
如果(!scope.VariableExists(“x”))
{
返回“x已删除”;
}
字符串结果=scope.GetVariable(“x”).ToString();
返回结果;
}
此示例取自。这里是一个使用表达式的运行时编译的工作示例。我借用了这个概念和大部分代码
static void Main(字符串[]args)
{
string input=“这是一个测试”;
string method=“Mid(x,2,4)”;//“x”表示输入值
字符串输出=转换(方法,输入);
Console.WriteLine(“结果:+输出”);
Console.ReadLine();
}
//使用给定的vbscript逻辑转换输入,并作为输出字符串返回
静态字符串转换(字符串vbscript、字符串输入)
{
var func=GetFunction(vbscript);
返回函数(输入);
}
//从可以应用的vbscript字符串创建函数
静态函数GetFunction(字符串vbscript)
{
//生成用于计算表达式的简单代码段
VBCodeProvider prov=新的VBCodeProvider();
CompilerResults results=prov.compileAsemblyFromSource(
新编译器参数(新[]{“System.Core.dll”}),
@"
导入系统
导入System.Linq.Expressions
导入Microsoft.VisualBasic
类MyConverter
公共共享函数Convert()作为表达式(属于Func(属于字符串,属于字符串))
返回函数(x)“+vbscript+@”
端函数
末级
"
);
//确保转换过程中没有发生错误
如果(results.Errors.Count==0)
{
//通过执行代码检索新准备的函数
var expr=(表达式)
results.CompiledAssembly.GetType(“MyConverter”)
.GetMethod(“Convert”).Invoke(null,null);
Func Func=expr.Compile();
//创建一个已编译的函数,以便应用和返回
返回函数;
}
其他的
{
返回null;
}
}
谢谢你的帖子,我现在正在研究这些选项。但是我有一个问题-可以动态运行脚本,但是可以将IronRuby/IronPython返回的结果返回到C变量中吗?应该是这样的。我认为你应该研究一下.NET4.0上的C#“dynamic”关键字。在早期版本的.NET上应该有一个解决方案,但我需要查找它。谢谢您的回答,我会将问题标记为已回答
public string evaluate(string x, string code)
{
scope.SetVariable("x", x);
scope.SetVariable("button", this.button);
try
{
ScriptSource source = engine.CreateScriptSourceFromString(code,
SourceCodeKind.Statements);
source.Execute(scope);
}
catch (Exception ex)
{
return "Error executing code: " + ex.ToString();
}
if (!scope.VariableExists("x"))
{
return "x was deleted";
}
string result = scope.GetVariable<object>("x").ToString();
return result;
}
static void Main(string[] args)
{
string input = "This is a test";
string method = "Mid(x, 2, 4)"; // 'x' represents the input value
string output = Convert(method, input);
Console.WriteLine("Result: " + output);
Console.ReadLine();
}
// Convert input using given vbscript logic and return as output string
static string Convert(string vbscript, string input)
{
var func = GetFunction(vbscript);
return func(input);
}
// Create a function from a string of vbscript that can be applied
static Func<string, string> GetFunction(string vbscript)
{
// generate simple code snippet to evaluate expression
VBCodeProvider prov = new VBCodeProvider();
CompilerResults results = prov.CompileAssemblyFromSource(
new CompilerParameters(new[] { "System.Core.dll" }),
@"
Imports System
Imports System.Linq.Expressions
Imports Microsoft.VisualBasic
Class MyConverter
Public Shared Function Convert() As Expression(Of Func(Of String, String))
return Function(x) " + vbscript + @"
End Function
End Class
"
);
// make sure no errors occurred in the conversion process
if (results.Errors.Count == 0)
{
// retrieve the newly prepared function by executing the code
var expr = (Expression<Func<string, string>>)
results.CompiledAssembly.GetType("MyConverter")
.GetMethod("Convert").Invoke(null, null);
Func<string, string> func = expr.Compile();
// create a compiled function ready to apply and return
return func;
}
else
{
return null;
}
}