CodeFluent 与 Interop.MSScriptControl.dll [英] CodeFluent vs Interop.MSScriptControl.dll

查看:25
本文介绍了CodeFluent 与 Interop.MSScriptControl.dll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个 32 位的服务,我们正在尝试迁移到 64 位.

We had a 32 bits service that we are trying to migrate to 64 bits.

我们使用 Interop.MSScriptControl.dll 来评估用户编写的 vb 脚本.

We were using Interop.MSScriptControl.dll to evaluate vb script written by users.

因为没有 MSScriptControl 的 64 位版本.我创建了一个在服务内部调用的进程.每次我们需要评估用户脚本时,我们都会调用该过程.尝试了这个解决方案后,我发现它真的很慢.

Since there is no 64 bits version of the MSScriptControl. I created a process that was called inside the service. Each time that we need to evaluate users scripts, we call the process. After trying this solution, I found it really slow.

我刚刚发现了可以评估 vb 脚本和 JavaScript 的 CodeFluentRuntimeClient 库.但是,它评估脚本的方式与 MSScriptControl 库完全不同.

I just discovered the CodeFluentRuntimeClient library that can evaluate vb script as well as JavaScript. However, the way it evaluates the script is complety different from MSScriptControl library.

我创建了一个简单的测试程序来评估用户编写的旧 vb 脚本.

I created a simple test program to evaluate the old vb script wrote by users.

public class VBScriptEvaluator
{
    public static dynamic Evaluate(string key, string script, IDictionary<string, object> parameterValuePair)
    {
        try
        {
            using (ScriptEngine engine = new ScriptEngine(ScriptEngine.VBScriptLanguage))
            {
                ParsedScript parsed = engine.Parse(string.Format(@"Function {0}()
{1}
End Function", key, script));

                if (script.Contains("NecUserProfile"))
                    engine.SetNamedItem("NecUserProfile", @"" + "ADMIN" + @""); //Hardcoded For now
                if (parameterValuePair != null && parameterValuePair.Count > 0)
                {
                    foreach (var para in parameterValuePair)
                        engine.SetNamedItem(para.Key, para.Value);
                }
                dynamic value = parsed.CallMethod(key);
                return (value != null) ? value.ToString() : string.Empty;
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

如果我这样使用,它工作正常:

If I use like this, it's working fine:

static void Main(string[] args)
{
    string key = "necGlobalValue";
    string script = @"necGlobalValue = ""ADMIN""";
    var result = VBScriptEvaluator.Evaluate(key, script, null); //ADMIN
}

像这样它也很好用:

static void Main(string[] args)
{
    Dictionary<string, object> parameterValuePair = new Dictionary<string, object>();
    parameterValuePair.Add("ZINVOICE_MARGIN_0", 141615427.8);
    parameterValuePair.Add("ZINVOICE_AMTNOTLIN_0", 187260276.84);
    var script = @"If (ZINVOICE_AMTNOTLIN_0) <> 0 Then
         SERVER_FLD0000001 = Abs(ZINVOICE_MARGIN_0) / ZINVOICE_AMTNOTLIN_0
    else
        SERVER_FLD0000001 = 0
    End If";
    var key = "SERVER_FLD0000001";
    var result = VBScriptEvaluator.Evaluate(key, script, parameterValuePair);
}

在之前的库中,它会自动检测将要评估的变量的类型.我可以将整数作为字符串传递,它会工作得很好.

In the previous library it was detecting automatically the type of the variables that will be evaluated. I can pass integers as string and it will work just fine.

如果我使用 ScripEngine 替换字典的值,它将失败:

If I replace the value of the dictionary like by using the ScripEngine, it will fail:

Dictionary<string, object> parameterValuePair = new Dictionary<string, object>();
parameterValuePair.Add("ZINVOICE_MARGIN_0", "141615427.8");
parameterValuePair.Add("ZINVOICE_AMTNOTLIN_0", "187260276.84");

此外,如果我这样做,我将无法获得用户 ADMIN.

Also, If I do this I'm not getting the user ADMIN.

string key = "necGlobalValue";
string script = @"necGlobalValue = ""NecUserProfile""";
var result = VBScriptEvaluator.Evaluate(key, script, null); // output NecUserProfile instead of ADMIN

顺便说一句,我试图提供尽可能多的细节,这就是为什么问题这么长.

And BTW I tried to give as much details, that's why the question is that long.

推荐答案

我通过将参数传递给函数而不是使用 SetNamedItem 函数使其工作.

I made it work by passing the parameters to the function instead of using the SetNamedItem function.

public class VBScriptEvaluator
{
    public static dynamic Evaluate(string key, string script, IDictionary<string, object> parameterValuePair = null)
    {
        try
        {
            using (ScriptEngine engine = new ScriptEngine(ScriptEngine.VBScriptLanguage))
            {
                List<object> parameters = new List<object>() { "ADMIN" };
                string extraParameters = string.Empty;
                if (parameterValuePair != null && parameterValuePair.Count > 0)
                {
                    extraParameters = "," + string.Join(",", parameterValuePair.Select(e => e.Key));
                    foreach (var para in parameterValuePair)
                        parameters.Add(para.Value);
                }
                string parsedScript = string.Format(@"Function {0}(NecUserProfile {2})
{1}
End Function", key, script, extraParameters);
                ParsedScript parsed = engine.Parse(parsedScript);

                dynamic value = parsed.CallMethod(key, parameters.ToArray());
                return (value != null) ? value.ToString() : string.Empty;
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

这里是如何使用它:

Dictionary<string, object> parameterValuePair = new Dictionary<string, object>()
{
    {"Param1", 100.0 },
    {"Param2", 10.0}
};
var script = @"If (Param2) <> 0 Then
     result = Param1 + Param2
else
    result = 1 + 2
End If";
var key = "result";
var result = VBScriptEvaluator.Evaluate(key, script, parameterValuePair); // output 110

这篇关于CodeFluent 与 Interop.MSScriptControl.dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆