簡體   English   中英

CodeFluent 與 Interop.MSScriptControl.dll

[英]CodeFluent vs Interop.MSScriptControl.dll

我們有一個 32 位服務,我們正嘗試將其遷移到 64 位。

我們使用Interop.MSScriptControl.dll來評估用戶編寫的 vb 腳本。

由於沒有 64 位版本的MSScriptControl 我創建了一個在服務內部調用的進程。 每次我們需要評估用戶腳本時,我們都會調用該過程。 嘗試了這個解決方案后,我發現它真的很慢。

我剛剛發現了可以評估 vb 腳本和 JavaScript 的CodeFluentRuntimeClient庫。 但是,它評估腳本的方式與MSScriptControl庫完全不同。

我創建了一個簡單的測試程序來評估用戶編寫的舊 vb 腳本。

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

如果我這樣使用,它工作正常:

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

在之前的庫中,它自動檢測將被評估的變量的類型。 我可以將整數作為字符串傳遞,它會工作得很好。

如果我使用 ScripEngine 替換字典的值,它將失敗:

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

另外,如果我這樣做,我將不會獲得用戶 ADMIN。

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

順便說一句,我試圖提供盡可能多的細節,這就是問題那么長的原因。

我通過將參數傳遞給函數而不是使用SetNamedItem函數來SetNamedItem工作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM