CodeFluent vs Interop.MSScriptControl.dll

本小妞迷上赌 提交于 2019-12-02 02:46:48

问题


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

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

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.

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.

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
}

Like this it works well too:

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.

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");

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.


回答1:


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;
        }
    }
}

And here's how to use it:

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


来源:https://stackoverflow.com/questions/39663430/codefluent-vs-interop-msscriptcontrol-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!